tZERO Issuance & Secondary Markets API

REST/JSON API for creating individual broker-dealer accounts, triggering and reviewing KYC on investors, browsing primary offerings and managing investments, linking bank accounts and moving funds, reading balances, retrieving market schedules and public price history/snapshots, and placing, listing and cancelling orders on the tZERO ATS. Authenticated with an x-apikey header plus a bearer JWT obtained from POST /auth/v1/api/token.

Operations 33

POST /pi/v1/accounts/individual Onboard Individual account #
PUT /pi/v1/accounts/{accountId}/users/{userId} Update user of the account #
GET /pi/v1/accounts/{accountId} Get account by ID #
GET /pi/v1/accounts/{accountId}/users/{userId}/financialInfo Get financial information for user #
PATCH /pi/v1/accounts/{accountId}/users/{userId}/financialInfo Add or update financial information for user #
POST /pi/v1/accounts/{accountId}/trustedContact Add trusted contact #
DELETE /pi/v1/accounts/{accountId}/trustedContact/{trustedContactUserId} Remove trusted contact #
GET /pi/v1/users/{userId}/kyc Get KYC status for user #
POST /pi/v1/users/{userId}/kyc Trigger KYC for user #
GET /pi/v1/assets Get assets
POST /pi/v1/assets/{assetId}/investments Create investment #
PUT /pi/v1/assets/{assetId}/investments Update investment #
PUT /pi/v1/assets/{assetId}/investments/{investmentId}/payment Add Payment details to the investment on file. #
POST /pi/v1/accounts/{accountId}/bankAccounts Add bank account #
GET /pi/v1/accounts/{accountId}/bankAccounts Get bank accounts #
DELETE /pi/v1/accounts/{accountId}/bankAccounts/{bankAccountId} Remove bank account #
POST /pi/v1/accounts/{accountId}/bankAccounts/{bankAccountId}/transfer Initiate Deposit/Withdrawal from/to the Customer's Account #
GET /pi/v1/accounts/{accountId}/balances Get Account Balance #
GET /pi/v1/investments/accounts/{accountId} Get all investments for account #
POST /pi/v1/investments/{investmentId}/submit Submit investment #
DELETE /pi/v1/investments/{investmentId} Cancel investment #
POST /pi/v1/assets/{assetId}/investments/{investmentId}/agreement Sign MSA for investment #
POST /auth/v1/api/token Get Bearer token #
POST /auth/v1/api/refresh Refresh Token #
GET /pi/v1/docs/assets/{assetId}/accounts/{accountId}/wire-instructions Download wire instructions. #
GET /markets/v1/schedules Get market schedules #
GET /markets/v1/mdt/public-pricehistory/{symbol} Get Price History for a Symbol
GET /markets/v1/mdt/public-snapshots/{symbol} Get marketdata snapshot for a symbol
GET /trading/v1/fee Calculates an estimated fee for the trade. #
POST /trading/v1/accounts/{accountId}/orders Creates an order for an Account #
GET /trading/v1/accounts/{accountId}/orders Gets All orders placed for an Account. #
GET /trading/v1/accounts/{accountId}/orders/{orderId} Retrieve a single order for the given Order Id #
DELETE /trading/v1/accounts/{accountId}/orders/{orderId} Attempts to a Cancel a OPEN Order #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/issuance-secondary-markets"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

tzero-issuance-secondary-markets-openapi.json Raw ↑
{"openapi":"3.0.3","info":{"title":"Issuance & Secondary Markets API","description":"APIs to Create Individual broker dealer accounts, Trigger KYC on the investors in the account, Review account information and KYC results, View Primary offering that are available to invest and manage investments in the assets."},"servers":[{"url":"https://gateway-web-api.tzero.com/app"}],"tags":[{"name":"Authentication","description":"Authenticating and Authorizing API request(token, refresh)."},{"name":"Onboarding","description":"Managing accounts and users (create account, KYC, trusted contact, financial info)."},{"name":"Investments","description":"Investments and assets (create, update, submit, cancel, agreements)."},{"name":"Documents","description":"Document generation for wire instructions."},{"name":"Bank Accounts","description":"Managing bank accounts linked to an investor account (add, list, delete, verify)."},{"name":"Balance","description":"Retrieving fiat balances and asset position balances for an account."},{"name":"Markets","description":"Market schedule information including pre-market, regular, and post-market hours."},{"name":"Trading","description":"Order management for secondary-market trading (fees, submit, cancel, list orders)."}],"paths":{"/pi/v1/accounts/individual":{"post":{"tags":["Onboarding"],"summary":"Onboard Individual account","description":"Onboard Individual with identity information. Requires agreement (terms & conditions) and transactionId.","operationId":"onboardIndividualAccount","security":[{"x-api-key":[],"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateIndividualAccountRequest"},"example":{"transactionId":"a0000000-0000-0000-0000-000000000001","investor":{"agreement":{"acceptedAccountsTermsAndCondition":true,"termsAcceptedAt":"2025-01-28T12:00:00","eSignatureFullName":"John M Doe"},"optOutOfTrustedContact":true,"email":"john.doe@example.com","firstName":"John","middleName":"M","lastName":"Doe","citizenshipCountry":"US","taxCountry":"US","dateOfBirth":"1990-01-31","employment":{"employmentStatus":"FULL_TIME_EMPLOYED","employerName":"Acme Corp","occupation":"Software Engineer"},"physicalAddress":{"street":"1122 King Road","street2":"Apt 12","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"mailingAddress":{"street":"456 Oak Ave","city":"New York","stateOrProvince":"NY","postalCode":"10002","country":"US"},"phoneNumbers":[{"countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550123","ext":"123","type":"PRIMARY"},{"countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550999","type":"ALTERNATE"}],"governmentIdentifiers":[{"type":"TIN","country":"US","identifier":"123456789"}]}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"},"example":{"id":"PR-1234-5678","type":"INDIVIDUAL","status":"ACTIVE","createdTs":"2025-12-11T11:30:42.534426Z","transactionId":"a0000000-0000-0000-0000-000000000001","investors":[{"type":"PRIMARY_USER","id":"43XSYHc0h4aU5cxMkqhIQn","email":"john.doe@example.com","firstName":"John","middleName":"M","lastName":"Doe","citizenshipCountry":"US","dateOfBirth":"1990-01-31","employment":{"employmentStatus":"FULL_TIME_EMPLOYED","employerName":"Acme Corp","occupation":"Software Engineer"},"physicalAddress":{"id":"2f3b2c1a-4c1b-4b1b-9d1a-111111111111","street":"1122 King Road","street2":"Apt 12","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"mailingAddress":{"id":"3a4b5c6d-7e8f-9a0b-1c2d-444444444444","street":"456 Oak Ave","city":"New York","stateOrProvince":"NY","postalCode":"10002","country":"US"},"phoneNumbers":[{"id":"4c2d3e4f-5a6b-7c8d-9e0f-222222222222","countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550123","ext":"123","type":"PRIMARY"},{"id":"5d3e4f5a-6b7c-8d9e-0f1a-333333333333","countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550999","type":"ALTERNATE"}],"governmentIdentifiers":[{"id":"aaaaaaaa-bbbb-cccc-dddd-333333333333","type":"TIN","country":"US","identifier":"123456789","createdTs":"2025-12-11T11:30:42.534426Z"}]}]}}}},"400":{"description":"Bad Request (validation failed or invalid payload). Body: `errors` array; each item has `code`, `message`, optional `field`.\n\n**Create-account business validation codes:**\n\n| Code | Meaning |\n|------|---------|\n| DATE_OF_BIRTH_REQUIRED | Date of birth is required. |\n| DATE_OF_BIRTH_INVALID | Date of birth format invalid; use YYYY-MM-DD. |\n| DATE_OF_BIRTH_IN_FUTURE | Date of birth cannot be in the future. |\n| DOB_NOT_ALLOWED | Date of birth not allowed; date cannot be more than 120 years in the past. |\n| INVESTOR_AGE_INSUFFICIENT | Investor must be at least 18 years old. |\n| TAX_COUNTRY_MUST_BE_US | Tax country must be US when physical address or citizenship is US. |\n| GOVERNMENT_IDENTIFIER_TYPE_INVALID | Gov ID type not allowed for this country (e.g. Expected TIN for US only; INTERNATIONAL_TIN or PASSPORT for non-US). |\n| PASSPORT_REQUIRED_FOR_NON_US | A passport is required when physical address is not in the US. |\n| GOVERNMENT_IDENTIFIER_COUNTRY_MISMATCH | Gov ID country must match investor's citizenship, or address country. |\n| GOVERNMENT_IDENTIFIER_LENGTH_INVALID | Government identifier length invalid for type/country. |\n| PHYSICAL_ADDRESS_REQUIRED | Physical address is required. |\n| CITIZENSHIP_COUNTRY_INVALID | Citizenship country must be two-letter ISO code. |\n| TAX_COUNTRY_INVALID | Tax country must be two-letter ISO code. |\n| ADDRESS_COUNTRY_INVALID | Address country must be two-letter ISO code. |\n| EMAIL_REQUIRED, EMAIL_INVALID | Email required / invalid format. |\n| FIRST_NAME_REQUIRED, LAST_NAME_REQUIRED | Name fields required. |\n| ACCOUNT_EMAIL_ALREADY_EXISTS | An account with this email already exists. |\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"dateOfBirth":{"summary":"DoB validation (dateOfBirth in future)","value":{"errors":[{"code":"DATE_OF_BIRTH_IN_FUTURE","message":"Date of birth cannot be in the future","field":"investor.dateOfBirth"}]}},"jurisdiction":{"summary":"Jurisdiction (country not allowed)","value":{"errors":[{"code":"JURISDICTION_COUNTRY_NOT_ALLOWED","message":"Country is not in the allowed list for account applications","field":"investor.physicalAddress.country"}]}},"govId":{"summary":"Gov ID (passport required for non-US)","value":{"errors":[{"code":"PASSPORT_REQUIRED_FOR_NON_US","message":"A passport number is required when physical address is not in the US","field":"investor.governmentIdentifiers"}]}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"422":{"description":"Unprocessable Entity — jurisdiction not allowed. Same body as 400 (`errors` array).\n\n**Create-account jurisdiction codes (422):**\n\n| Code | Meaning |\n|------|---------|\n| JURISDICTION_COUNTRY_NOT_ALLOWED | Country is not in the allowed list for account applications. |\n| JURISDICTION_STATE_REQUIRED_FOR_US | State (region) is required when country is US. |\n| JURISDICTION_STATE_FORMAT_INVALID | State must be a two-character code when country is US. |\n| JURISDICTION_STATE_NOT_ALLOWED | State is not in the allowed list for account applications. |\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"jurisdictionCountry":{"summary":"Jurisdiction country not allowed","value":{"errors":[{"code":"JURISDICTION_COUNTRY_NOT_ALLOWED","message":"Country is not in the allowed list for account applications","field":"investor.physicalAddress.country"}]}}}}}},"500":{"description":"Internal Server Error"}}}},"/pi/v1/accounts/{accountId}/users/{userId}":{"put":{"tags":["Onboarding"],"summary":"Update user of the account","description":"Updates a user on an existing account. Validates that the user belongs to the account.\nAll request fields are optional. Provided fields that are editable are updated or overridden; omitted fields are left unchanged.\nFor array fields such as phoneNumbers and governmentIdentifiers, the request body carries replace semantics: the array you send is the full desired set.\nAny existing items omitted from the array are treated as desired to be deleted. When null/absent, fields are unchanged.\n","operationId":"updateInvestor","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"},{"name":"userId","in":"path","required":true,"description":"Identity ID of the user to update (must belong to the account).","schema":{"type":"string"},"example":"43XSYHc0h4aU5cxMkqhIQn"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvestorRequest"},"examples":{"updateInvestor":{"summary":"Update investor","value":{"transactionId":"a0000000-0000-0000-0000-000000000001","investor":{"firstName":"John","middleName":"M","lastName":"Doe","citizenshipCountry":"US","taxCountry":"US","dateOfBirth":"1990-01-31","employment":{"employmentStatus":"FULL_TIME_EMPLOYED","employerName":"Acme Corp","occupation":"Software Engineer"},"physicalAddress":{"street":"1122 King Road","street2":"Apt 12","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"mailingAddress":{"street":"456 Oak Ave","city":"New York","stateOrProvince":"NY","postalCode":"10002","country":"US"},"phoneNumbers":[{"countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550123","ext":"123","type":"PRIMARY"}],"governmentIdentifiers":[{"type":"TIN","country":"US","identifier":"123456789"}]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestorUpdateResponse"},"example":{"investor":{"type":"PRIMARY_USER","id":"43XSYHc0h4aU5cxMkqhIQn","email":"john.doe@example.com","firstName":"John","middleName":"M","lastName":"Doe","citizenshipCountry":"US","dateOfBirth":"1990-01-31","employment":{"employmentStatus":"FULL_TIME_EMPLOYED","employerName":"Acme Corp","occupation":"Software Engineer"},"physicalAddress":{"id":"2f3b2c1a-4c1b-4b1b-9d1a-111111111111","street":"1122 King Road","street2":"Apt 12","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"mailingAddress":{"id":"3a4b5c6d-7e8f-9a0b-1c2d-444444444444","street":"456 Oak Ave","city":"New York","stateOrProvince":"NY","postalCode":"10002","country":"US"},"phoneNumbers":[{"id":"4c2d3e4f-5a6b-7c8d-9e0f-222222222222","countryCode":"1","countryCodeAlpha":"US","nationalNumber":"2125550123","ext":"123","type":"PRIMARY"}],"governmentIdentifiers":[{"id":"aaaaaaaa-bbbb-cccc-dddd-333333333333","type":"TIN","country":"US","identifier":"123456789","createdTs":"2025-12-11T11:30:42.534426Z"}]},"transactionId":"a0000000-0000-0000-0000-000000000001"}}}},"400":{"description":"Bad Request (validation / user does not belong to account / invalid payload). Body: `errors` array with `code`, `message`, optional `field`.\n\n**Update-user business validation codes:**\n\n| Code | Meaning |\n|------|---------|\n| INVESTOR_DOES_NOT_BELONG_TO_ACCOUNT | The specified user does not belong to this account. |\n| DATE_OF_BIRTH_INVALID, DATE_OF_BIRTH_IN_FUTURE, DOB_NOT_ALLOWED, INVESTOR_AGE_INSUFFICIENT | Same as create (DoB rules). |\n| TAX_COUNTRY_MUST_BE_US | Tax country must be US when physical address or citizenship is US. |\n| GOVERNMENT_IDENTIFIER_TYPE_INVALID | Gov ID type not allowed for this country (e.g. TIN for US only). |\n| PASSPORT_REQUIRED_FOR_NON_US | A passport is required when physical address is not in the US. |\n| GOVERNMENT_IDENTIFIER_COUNTRY_MISMATCH | Gov ID country must match user, citizenship, or address country. |\n| GOVERNMENT_IDENTIFIER_LENGTH_INVALID | Government identifier length invalid. |\n| GOVERNMENT_IDENTIFIER_AT_LEAST_ONE_REQUIRED | At least one government identifier must be retained; cannot delete all. |\n| FIELD_NOT_MUTABLE | Field cannot be changed (e.g. physicalAddress.country change not allowed). |\n| FIRST_NAME_REQUIRED, LAST_NAME_REQUIRED | When provided, must not be blank. |\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"govIdType":{"summary":"Gov ID type invalid (e.g. INTERNATIONAL_TIN when US)","value":{"errors":[{"code":"GOVERNMENT_IDENTIFIER_TYPE_INVALID","message":"Government Identifier type needs to be TIN for US residents.","field":"investor.governmentIdentifiers"}]}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/accounts/{accountId}":{"get":{"tags":["Onboarding"],"summary":"Get account by ID","operationId":"getAccountById","parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"}],"security":[{"x-api-key":[],"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}},"400":{"description":"Bad Request (e.g. invalid accountId format). Body: `errors` array with `code`, `message`, optional `field`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden (caller does not have access to this account).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found (account does not exist or caller has no access). Body: `errors` array; code typically `NOT_FOUND`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"notFound":{"summary":"Account not found","value":{"errors":[{"code":"NOT_FOUND","message":"Account not found: {accountId}"}]}}}}}},"500":{"description":"Internal Server Error (e.g. account retrieval failed). Body: `errors` array; code e.g. `ACCOUNT_RETRIEVAL_FAILED`, `INTERNAL_ERROR`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/pi/v1/accounts/{accountId}/users/{userId}/financialInfo":{"get":{"tags":["Onboarding"],"summary":"Get financial information for user","description":"Returns financial information (net worth, annual income) for the specified user. Validates that the user belongs to the account; caller must have access to the account.\n","operationId":"getFinancialInfo","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"},{"name":"userId","in":"path","required":true,"description":"User ID must belong to the account.","schema":{"type":"string"},"example":"43XSYHc0h4aU5cxMkqhIQn"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialInfoResponse"},"example":{"accountId":"PR-1234-5678","netWorth":500000,"annualIncome":120000,"annualIncomeLastChangedTs":"2025-12-11T11:30:42.534426Z"}}}},"400":{"description":"Bad Request (e.g. user does not belong to account). Body: `errors` array; code e.g. INVESTOR_DOES_NOT_BELONG_TO_ACCOUNT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}},"patch":{"tags":["Onboarding"],"summary":"Add or update financial information for user","description":"Add or update financial information for the specified user. Validates that the user belongs to the account; then updates only the provided fields (net worth, annual income). All request fields are optional; omitted fields are left unchanged.\n","operationId":"patchFinancialInfo","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"},{"name":"userId","in":"path","required":true,"description":"User ID must belong to the account.","schema":{"type":"string"},"example":"43XSYHc0h4aU5cxMkqhIQn"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchFinancialInfoRequest"},"example":{"transactionId":"a0000000-0000-0000-0000-000000000001","netWorth":500000,"annualIncome":120000}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialInfoResponse"},"example":{"accountId":"PR-1234-5678","netWorth":500000,"annualIncome":120000,"annualIncomeLastChangedTs":"2025-12-11T11:30:42.534426Z","transactionId":"a0000000-0000-0000-0000-000000000001"}}}},"400":{"description":"Bad Request (validation failed or user does not belong to account). Body: `errors` array; e.g. NET_WORTH_INVALID, ANNUAL_INCOME_INVALID, INVESTOR_DOES_NOT_BELONG_TO_ACCOUNT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/accounts/{accountId}/trustedContact":{"post":{"tags":["Onboarding"],"summary":"Add trusted contact","description":"Add a trusted contact to the account's primary user. If the account already has a trusted contact, the request fails with a conflict.","operationId":"addTrustedContact","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustedContactRequest"},"example":{"transactionId":"a0000000-0000-0000-0000-000000000001","email":"trusted.contact@example.com","firstName":"Jane","lastName":"Contact","physicalAddress":{"street":"456 Oak Avenue","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"phoneNumber":"+12125550456"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrustedContactResponse"},"example":{"trustedContact":{"id":"7e8f9a0b-1c2d-3e4f-5a6b-777777777777","email":"trusted.contact@example.com","firstName":"Jane","lastName":"Contact","physicalAddress":{"street":"456 Oak Avenue","city":"New York","stateOrProvince":"NY","postalCode":"10001","country":"US"},"phoneNumber":"+12125550456"},"transactionId":"a0000000-0000-0000-0000-000000000001"}}}},"400":{"description":"Bad Request (validation or trusted contact already exists). Same error body; see ErrorResponse and x-businessValidationErrorCodes in components.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/accounts/{accountId}/trustedContact/{trustedContactUserId}":{"delete":{"tags":["Onboarding"],"summary":"Remove trusted contact","description":"Remove the trusted contact from the account's primary user. The path parameter must be the identity ID of the current trusted contact.","operationId":"removeTrustedContact","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"description":"Account identifier.","schema":{"type":"string"},"example":"PR-1234-5678"},{"name":"trustedContactUserId","in":"path","required":true,"description":"Identity ID of the trusted contact to remove (must match the account's current trusted contact).","schema":{"type":"string"},"example":"7e8f9a0b-1c2d-3e4f-5a6b-777777777777"}],"responses":{"204":{"description":"No Content"},"400":{"description":"Bad Request (trustedContactUserId does not match account's trusted contact)"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/users/{userId}/kyc":{"get":{"tags":["Onboarding"],"summary":"Get KYC status for user","description":"Retrieve the KYC status for a specific user (identity ID). Returns status, and when document verification (DocV) is required, may include docUrl and qrMessage for the user to complete verification.\n\n**KYC status values:**\n| Status | Meaning |\n|--------|---------|\n| PENDING | KYC submitted; pending manual review or document verification. User may need to complete DocV (see docUrl/qrMessage when present). |\n| APPROVED | KYC approved; user is verified. |\n| NOT_APPROVED | KYC not approved (non-retryable). |\n| NOT_APPROVED_RETRYABLE | KYC not approved; user may retry. |\n| VENDOR_ERROR / CANNOT_PROCESS | Vendor or processing error; may retry later. |\n\n**When to expect docUrl and qrMessage:** These fields are populated when status is PENDING and document verification (DocV) is required. The client can present docUrl (link) or qrMessage (QR code image data) to the user so they can upload their ID document. When docStatus is USER_ACTION_REQUIRED, the user must complete the DocV flow; after they do, docStatus moves to PROCESSING then COMPLETED (or EXPIRED/FAILED).\n","operationId":"getUserKycStatus","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"description":"Identity (user) ID.","schema":{"type":"string"},"example":"43XSYHc0h4aU5cxMkqhIQn"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostKycResponse"},"example":{"userId":"43XSYHc0h4aU5cxMkqhIQn","kycResult":{"status":"APPROVED","id":"b1c2d3e4-f5a6-7b8c-9d0e-555555555555","createdTs":"2025-12-11T11:35:00.000000","modifiedTs":"2025-12-11T11:40:00.000000"}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden (caller does not have access to this user's KYC).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found (no KYC record for this user, or user does not exist). Body: `errors` array; code typically `KYC_NOT_FOUND`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"kycNotFound":{"summary":"KYC not found for user","value":{"errors":[{"code":"KYC_NOT_FOUND","message":"KYC not found for user: {userId}"}]}}}}}},"500":{"description":"Internal Server Error (e.g. KYC retrieval failed). Body: `errors` array; code e.g. `KYC_RETRIEVAL_ERROR`, `INTERNAL_ERROR`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Onboarding"],"summary":"Trigger KYC for user","description":"Trigger a KYC check for a specific user.","operationId":"triggerKyc","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"userId","in":"path","required":true,"description":"Identity (user) ID.","schema":{"type":"string"},"example":"43XSYHc0h4aU5cxMkqhIQn"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TriggerKycRequest"},"example":{"transactionId":"a0000000-0000-0000-0000-000000000001"}}},"required":true},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostKycResponse"},"example":{"userId":"43XSYHc0h4aU5cxMkqhIQn","kycResult":{"status":"PENDING","id":"b1c2d3e4-f5a6-7b8c-9d0e-555555555555","createdTs":"2025-12-11T11:35:00.000000"},"transactionId":"a0000000-0000-0000-0000-000000000001"}}}},"400":{"description":"Bad Request (validation or invalid payload)"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/assets":{"get":{"tags":["Investments"],"summary":"Get assets","description":"Returns list of available assets.","security":[{"x-api-key":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetsResponse"},"examples":{"success":{"summary":"Example response","value":{"assets":[{"assetId":"39737","symbol":"AF","assetName":"Abstract Face","assetDescription":"","assetType":{"code":"COMMON_STOCK","label":"Common Stock","description":"Common Stock."},"requiresAccreditation":false,"pricePerShare":10,"minimumInvestment":50,"maximumInvestment":100000,"status":"OPEN","offeringCloseDate":"2026-06-30T23:59:59-04:00","offering":{"code":"REG_D_506C","label":"Reg D 506 (c)","description":"Reg D 506 (c) offering."},"countries":["US"],"paymentTypes":[{"code":"WIRE","label":"WIRE","description":"Wire Transfer."}]}]}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/pi/v1/assets/{assetId}/investments":{"post":{"tags":["Investments"],"summary":"Create investment","description":"Create a new investment for an asset.\n\n`numberOfShares` is optional; when it is not provided investment `amount`\nis used to compute the `numberOfShares`. If the shares cannot be computed or If fractional shares is not supported , the request gets rejected with `INVALID_AMOUNT_AND_SHARES`.\n\nFor Reg CF assets, regCFInvestmentTermsAccepted must be true.\nAnnual income and net worth are required for Reg A and Reg CF.\n","operationId":"createInvestment","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"assetId","in":"path","required":true,"description":"Asset identifier","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInvestmentRequest"},"examples":{"withInvestmentAmount":{"summary":"Investment amount provided — numberOfShares computed automatically","value":{"accountId":"1234-5678","transactionId":"a0000000-0000-0000-0000-000000000001","amount":499.51}},"withInvestmentAmountAndShares":{"summary":"Investment amount and numberOfShares provided","value":{"accountId":"1234-5678","transactionId":"a0000000-0000-0000-0000-000000000002","amount":499.51,"numberOfShares":239}},"withInvesmentAmountAndRegCF":{"summary":"Reg CF asset (terms acceptance required)","value":{"accountId":"1234-5678","transactionId":"a0000000-0000-0000-0000-000000000003","amount":499.51,"regCFInvestmentTermsAccepted":true}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentDetails"},"example":{"investmentId":"inv-123","amount":1000,"numberOfShares":1000,"fundedAmount":0,"status":"CREATED","assetId":"39737","transactionId":"txn-001","paymentType":"WIRE","createdTs":"2025-12-11T11:30:42.534426Z","modifiedTs":"2025-12-11T11:30:42.534426Z"}}}},"400":{"description":"Bad Request (validation failed or invalid payload). Body: `errors` array; each item has `code`, `message`, optional `field`.\n\n**Create investment — error codes:**\n\n| Code | Meaning |\n|------|---------|\n| ACCOUNT_ID_REQUIRED | Account identifier is required. |\n| TRANSACTION_ID_REQUIRED | Transaction ID is required. |\n| AMOUNT_REQUIRED | Amount is required. |\n| AMOUNT_INVALID | Amount must be positive. |\n| NUMBER_OF_SHARES_INVALID | Number of shares must be positive when provided. |\n| ASSET_NOT_OPEN | Asset is not open for investment. |\n| INVALID_AMOUNT_AND_SHARES | `amount` is not a valid investment in the asset. If `details` object is available it may contain following fields `recommendedAmount`, `recommendedNumberOfShares`, and `pricePerShare`. |\n| REG_CF_TERMS_NOT_ACCEPTED | Reg CF investment terms must be accepted (Reg CF assets). |\n| REG_CF_TERMS_ONLY_APPLICABLE_TO_REG_CF | Reg CF terms acceptance is only applicable to Reg CF assets. |\n| ANNUAL_INCOME_REQUIRED | Annual income is required for Reg A and Reg CF investments. |\n| NET_WORTH_REQUIRED | Net worth is required for Reg A and Reg CF investments. |\n| INVESTMENT_CREATE_ERROR | Investment could not be created. |\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"examples":{"amountRequired":{"summary":"Amount required","value":{"errors":[{"code":"AMOUNT_REQUIRED","message":"Amount is required","field":"amount"}]}},"assetNotOpen":{"summary":"Asset not open","value":{"errors":[{"code":"ASSET_NOT_OPEN","message":"Cannot create investment; asset is not open for investment."}]}},"amountAndSharesMismatch":{"summary":"Amount and Number of Shars mismatch — recommended amounts in `details` object.","value":{"errors":[{"code":"INVALID_AMOUNT_AND_SHARES","message":"Investment amount must be adjusted to match Asset's price per share.","field":"amount","details":{"recommendedAmount":499.51,"recommendedNumberOfShares":239,"pricePerShare":2.09}}]}},"amountBelowMin":{"summary":"Investment Amount below requested minimum amount for the asset","value":{"errors":[{"code":"INVALID_AMOUNT_AND_SHARES","message":"Investment amount {2} is below the minimum required to purchase one share of the Asset.","field":"amount"}]}}}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found (account or primary user)"},"500":{"description":"Internal Server Error"}}},"put":{"tags":["Investments"],"summary":"Update investment","description":"Update an existing investment (amount, payment details, etc.).\nInvestment must belong to the account and match the asset in the path.\nPayment details can also be configured via the dedicated PUT `.../payment` endpoint.\nWhen `amount` is provided without `numberOfShares`, the amount is validated against the asset. On mismatch, a `INVALID_AMOUNT_AND_SHARES` error is returned.\n","operationId":"updateInvestment","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"assetId","in":"path","required":true,"description":"Asset identifier.","schema":{"type":"string"},"example":"39737"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateInvestmentRequest"},"example":{"accountId":"PR-1234-5678","investmentId":"U7F7D95Y","transactionId":"a0000000-0000-0000-0000-000000000002","amount":1500,"paymentType":"ACH","bankAccountId":"fia-abc-123"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvestmentDetails"},"example":{"investmentId":"U7F7D95Y","amount":1500,"fundedAmount":0,"status":"CREATED","assetId":"39737","transactionId":"a0000000-0000-0000-0000-000000000002","paymentType":"ACH","createdTs":"2025-12-11T11:30:42.534426Z","modifiedTs":"2025-12-11T12:00:00.000000Z"}}}},"400":{"description":"Bad Request (validation failed or invalid payload). Body: `errors` array; each item has `code`, `message`, optional `field`.\n\n**Update investment — error codes:**\n\n| Code | Meaning |\n|------|---------|\n| ACCOUNT_ID_REQUIRED | Account identifier is required. |\n| TRANSACTION_ID_REQUIRED | Transaction ID is required. |\n| AMOUNT_INVALID | Amount must be positive when provided. |\n| NUMBER_OF_SHARES_INVALID | Number of shares must be positive when provided. |\n| INVESTMENT_UPDATE_NOT_ALLOWED | Investment update not allowed. |\n| INVESTMENT_STATUS_NOT_ALLOWED_TO_UPDATE | Investment not allowed to be updated in current status. |\n| ASSET_NOT_RELATED_TO_INVESTMENT | Asset is not related to the investment (path assetId mismatch). |\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found (account, primary user, or investment)"},"500":{"description":"Internal Server Error"}}}},"/pi/v1/assets/{assetId}/investments/{investmentId}/payment":{"put":{"tags":["Investments"],"summary":"Add Payment details to the investment on file.","description":"Add payment details to an existing investment. This is a separate step from\nupdating investment amount/shares. Only WIRE and ACH payment types are supported.\nFor ACH, a `bankAccountId` (linked bank account) must be provided.\n","operationId":"addInvestmentPayment","security":[{"x-api-key":[],"bearerAuth":[]}],"parameters":[{"name":"assetId","in":"path","required":true,"description":"Asset identifier.","schema":{"type":"string"},"example":"39737"},{"name":"investmentId","in":"path","required":true,"description":"Investment identifier.","schema":{"type":"string"},"example":"U7F7D95Y"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePaymentRequest"},"example":{"accountId":"PR-1234-5678","paymentType":"ACH","bankAcco

# --- truncated at 32 KB (107 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/tzero/refs/heads/main/openapi/tzero-issuance-secondary-markets-openapi.json