openapi: 3.1.0 info: title: Vistra Incorporations API description: >- The Vistra Incorporations API enables programmatic submission of company incorporation requests in supported jurisdictions. Currently available for the British Virgin Islands (BVI) on an invite-only basis. The API supports a three-step workflow: (1) generate a pre-signed S3 document upload URL, (2) confirm document upload completion, and (3) submit the full incorporation request with entity details, stakeholders, shareholding structure, and compliance data. Authentication uses OAuth2 bearer tokens obtained from the Vistra Developer Portal. version: '1.0' contact: name: Vistra Developer Support url: https://devportal.vistra.com/ license: name: Vistra Terms of Use url: https://www.vistra.com/terms-of-use termsOfService: https://www.vistra.com/terms-of-use externalDocs: description: Vistra Incorporations API Documentation url: https://help.vistra.com/en/articles/10351085-vistra-incorporations-api-british-virgin-islands servers: - url: https://api.vistra.com description: Vistra Production API tags: - name: Documents description: Document upload URL generation and completion notification - name: Incorporations description: Company incorporation request submission and management security: - OAuth2Bearer: [] paths: /v1/external/documents/upload-url: post: operationId: generateDocumentUploadUrl summary: Generate Document Upload URL description: >- Generates a pre-signed S3 URL for uploading a supporting document for an incorporation request. The response includes a document ID and an upload URL that is valid for one minute. Upload the file directly to the pre-signed URL using an HTTP PUT request, then call the upload-complete endpoint with the document ID to notify Vistra the upload has finished. tags: - Documents requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/DocumentUploadRequest' responses: '200': description: Pre-signed upload URL and document ID content: application/json: schema: $ref: '#/components/schemas/DocumentUploadResponse' '400': description: Invalid request parameters content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized - Invalid or missing bearer token content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /v1/external/documents/{id}/upload-complete: post: operationId: completeDocumentUpload summary: Complete Document Upload description: >- Notifies Vistra that a document upload to the pre-signed S3 URL has completed successfully. This endpoint must be called after the file has been uploaded directly to the pre-signed URL. The response confirms the document ID and returns file metadata including filename and size. The document ID is then used when submitting the incorporation request. tags: - Documents parameters: - name: id in: path required: true description: The document ID returned by the generate-upload-url endpoint schema: type: string responses: '200': description: Document upload confirmed with file details content: application/json: schema: $ref: '#/components/schemas/DocumentUploadCompleteResponse' '400': description: Invalid document ID or upload not yet completed content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Document ID not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /v1/external/incorporations: post: operationId: createIncorporation summary: Create Incorporation description: >- Submits a company incorporation request to Vistra after all supporting documents have been uploaded and their IDs recorded. The request body includes comprehensive entity information, individual and corporate stakeholders, shareholding structure, and compliance data. This endpoint is currently available for British Virgin Islands (BVI) incorporations on an invite-only basis. tags: - Incorporations requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/IncorporationRequest' responses: '201': description: Incorporation request submitted successfully content: application/json: schema: $ref: '#/components/schemas/IncorporationResponse' '400': description: Invalid incorporation request data content: application/json: schema: $ref: '#/components/schemas/Error' '401': description: Unauthorized - Invalid or missing bearer token content: application/json: schema: $ref: '#/components/schemas/Error' '403': description: Forbidden - API access is invite-only content: application/json: schema: $ref: '#/components/schemas/Error' '422': description: Unprocessable entity - validation errors in request body content: application/json: schema: $ref: '#/components/schemas/ValidationError' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' get: operationId: listIncorporations summary: List Incorporations description: >- Returns a list of incorporation requests submitted through the API, including their current status and reference identifiers. tags: - Incorporations parameters: - name: status in: query required: false description: Filter by incorporation status schema: type: string enum: [pending, processing, completed, rejected] - name: offset in: query required: false description: Pagination offset schema: type: integer default: 0 - name: limit in: query required: false description: Number of records per page schema: type: integer default: 20 maximum: 100 responses: '200': description: List of incorporation requests content: application/json: schema: $ref: '#/components/schemas/IncorporationList' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' /v1/external/incorporations/{id}: get: operationId: getIncorporation summary: Get Incorporation description: Returns the current status and details of a specific incorporation request. tags: - Incorporations parameters: - name: id in: path required: true description: Incorporation request identifier schema: type: string responses: '200': description: Incorporation request details content: application/json: schema: $ref: '#/components/schemas/IncorporationResponse' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Error' '404': description: Incorporation not found content: application/json: schema: $ref: '#/components/schemas/Error' '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/Error' components: securitySchemes: OAuth2Bearer: type: http scheme: bearer description: >- OAuth2 bearer token obtained from the Vistra Developer Portal. Include in the Authorization header as "Bearer {token}". schemas: DocumentUploadRequest: type: object description: Request to generate a pre-signed document upload URL required: - filename - contentType properties: filename: type: string description: Name of the file to upload example: "passport-john-doe.pdf" contentType: type: string description: MIME type of the file example: "application/pdf" description: type: string description: Optional description of the document DocumentUploadResponse: type: object description: Pre-signed S3 URL and document ID for uploading a document properties: documentId: type: string description: Unique identifier for this document, used in subsequent calls uploadUrl: type: string description: Pre-signed S3 URL for HTTP PUT file upload (valid for 1 minute) expiresAt: type: string format: date-time description: Expiry timestamp of the upload URL DocumentUploadCompleteResponse: type: object description: Confirmation that a document upload has been registered properties: documentId: type: string description: Document identifier filename: type: string description: Uploaded filename size: type: integer description: File size in bytes status: type: string description: Upload status enum: [completed, pending, failed] IncorporationRequest: type: object description: >- Full incorporation request including entity details, stakeholders, shareholding structure, and compliance information. required: - jurisdiction - companyName - entityType properties: jurisdiction: type: string description: Jurisdiction for incorporation (e.g. BVI) example: "BVI" companyName: type: string description: Proposed company name entityType: type: string description: Type of entity to incorporate enum: [business_company, llc, limited_partnership] shareStructure: $ref: '#/components/schemas/ShareStructure' registeredAgent: $ref: '#/components/schemas/RegisteredAgent' individuals: type: array description: Individual stakeholders (directors, shareholders, beneficial owners) items: $ref: '#/components/schemas/IndividualStakeholder' corporates: type: array description: Corporate stakeholders items: $ref: '#/components/schemas/CorporateStakeholder' documentIds: type: array description: IDs of previously uploaded supporting documents items: type: string notes: type: string description: Additional notes or special instructions ShareStructure: type: object description: Shareholding structure for the company properties: authorizedShares: type: integer description: Total number of authorized shares parValue: type: number description: Par value per share currency: type: string description: Currency for par value (e.g. USD) RegisteredAgent: type: object description: Registered agent details properties: name: type: string address: type: string jurisdiction: type: string IndividualStakeholder: type: object description: An individual stakeholder in the incorporated entity required: - firstName - lastName - role properties: firstName: type: string lastName: type: string dateOfBirth: type: string format: date nationality: type: string role: type: string enum: [director, shareholder, beneficial_owner, secretary] shares: type: integer description: Number of shares held (for shareholders) documentIds: type: array items: type: string description: IDs of identity documents for this stakeholder CorporateStakeholder: type: object description: A corporate entity as a stakeholder properties: companyName: type: string jurisdiction: type: string registrationNumber: type: string role: type: string enum: [shareholder, director] shares: type: integer documentIds: type: array items: type: string IncorporationResponse: type: object description: Response after submitting an incorporation request properties: id: type: string description: Unique incorporation request identifier status: type: string description: Current status of the incorporation request enum: [pending, processing, completed, rejected] companyName: type: string jurisdiction: type: string submittedAt: type: string format: date-time estimatedCompletionDate: type: string format: date referenceNumber: type: string description: Vistra's internal reference number IncorporationList: type: object properties: total: type: integer offset: type: integer limit: type: integer items: type: array items: $ref: '#/components/schemas/IncorporationResponse' Error: type: object description: API error response properties: code: type: string description: Error code message: type: string description: Human-readable error message details: type: string description: Additional error details ValidationError: type: object description: Validation error with field-level details properties: code: type: string message: type: string errors: type: array items: type: object properties: field: type: string message: type: string