Skip to content
Seismic Orchestration

Customers

These are end-user customers, individuals or businesses that your product onboards onto the platform. They're scoped to your org. They are NOT the same thing as your org's own KYB onboarding, which lives under Orgs → KYB profile.

The surface is polymorphic. A Customer carries a type discriminator ("individual" or "business"). Profile data lives in a nested profile sub-object whose shape is picked by type (a KycProfile for individuals, a KybProfile for businesses). Every endpoint accepts either kind on the same URL and returns the right shape based on type.

All endpoints under /customers require auth, either an Api-Key: <key> (org-scoped, recommended) or Authorization: Bearer <access-token> (dashboard session). Customers are filtered to the org bound to the credential. Curl snippets assume $SEISMIC_ORCHESTRATION_URL and $SEISMIC_ORCHESTRATION_API_KEY, see Auth for the full model.

Endpoints

Lifecycle

Every customer carries a kyc_link inline on every read. Auto-minted at create-time. No separate endpoint needed to fetch it.

Documents

Orders

An order is the record created when a quote is accepted (see POST /quotes/:id/accept).

Per-customer accounts

Live under Accounts: the create + read endpoints for a customer's fiat / crypto accounts all hang off /customers/:id/accounts/* but are documented in the Accounts section to keep this page focused on KYC/KYB.

Types

Customer

A polymorphic envelope returned by retrieve and update. The envelope carries the identity discriminator (type), the saved profile, and the inline kyc_link. Verification status (KYC for individuals, KYB for businesses) is not denormalized onto this record. Read it from GET /customers/:id/kyc/state instead.

FieldTypeNotes
type"individual" | "business"Discriminator. Picks the shape of profile (KYC vs KYB).
profileKycProfile | KybProfileKycProfile when type === "individual", KybProfile when type === "business".
kyc_linkHostedKycLinkAlways present. Same field name for both kinds. The url path encodes the kind. Auto-minted at customer create. Rotate via POST /customers/:id/kyc-link/rotate.

POST /customers returns the smaller { type, id, kyc_link } shape (no profile echoed back). Pass id back on every subsequent call.

Profile fields can be partially populated pre-submit. The wizard saves drafts via PUT /customers/:id/kyc/profile. Submit-time validation runs on POST /customers/:id/kyc/submit.

The partner-issued, Seismic-hosted KYC/KYB link. Every customer carries one inline on every read. No separate fetch endpoint exists. Partners share the url with their end-customer, who lands on a standalone wizard at /kyc-link/<kind>/<token> and fills in their own verification. The URL itself is the credential, so anyone with it can read and write that one customer's profile, upload documents, and submit. It cannot read other customers, mint other links, or act on the org.

FieldTypeNotes
tokenstringOpaque, fixed-width (49 chars: klink_ + 43 base64url chars). Same plaintext embedded in url. Surfaced separately so partners running their own branded wizard can build URLs against their own frontend host.
urlstringAbsolute URL of the form <origin>/kyc-link/<kind>/<token> where <kind> is ind (individual), biz (business), or bi (business-individual). The origin is https://orchestration.seismic.systems on production and https://orchestration.seismictest.net on sandbox. Self-hosted deployments configure it via the APP_BASE_URL env var. Send this URL as-is to your end-customer. No client-side prefixing needed.

No expiry, no revocation: if a token leaks, rotate it. Each rotation overwrites the token in place and 404s the previous URL.

Individual customer (type: "individual"): url carries the ind segment:

{
  "token": "klink_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w",
  "url": "https://orchestration.seismic.systems/kyc-link/ind/klink_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w"
}

Business customer (type: "business"): same field name kyc_link, but url carries the biz segment:

{
  "token": "klink_b9c8d7e6f5g4h3i2j1k0l9m8n7o6p5q4r3s2t1u0v9w8x",
  "url": "https://orchestration.seismic.systems/kyc-link/biz/klink_b9c8d7e6f5g4h3i2j1k0l9m8n7o6p5q4r3s2t1u0v9w8x"
}

Sandbox-issued links carry the same shape with the seismictest.net origin, e.g. https://orchestration.seismictest.net/kyc-link/ind/klink_….

The bi segment is reserved for business-individual links (B2B2C end-users of a business customer). The wizard for that flow isn't part of the public API surface yet.

Address

Shared shape used in profile.addresses.residential, profile.addresses.mailing (KYC), profile.addresses.registered, profile.addresses.physical (KYB, via OperatingAddress), and per-UBO profile.associated_persons[].address (KYB).

FieldTypeRequired at submitNotes
line1stringyesAt least 4 characters.
line2stringno
citystringyes
statestringconditionalISO-3166-2 subdivision (e.g. "NY"). Required when the country's address format includes a state / region (e.g. US, CA, HK); omit it for countries that don't use one (e.g. GB).
postal_codestringconditionalRequired when the country's address format requires a postal code, and format-checked whenever supplied.
countrystring (ISO-3166 α-2)yesTwo-letter code, e.g. "US". See Country codes.
transliterated_addressTransliteratedAddressconditionalRequired when any canonical field above contains non-Latin-1 characters.

No PO boxes.

Both conditional rules resolve per country. GET /customers/address-requirements answers them for one country ahead of submit, so a form can hide the fields that country's address format doesn't have.

OperatingAddress

profile.addresses.physical (KYB) only. Every Address field, sent inline.

FieldTypeRequired at submitNotes
remotebooleannoDeprecated. Set addresses.operating_is_remote instead. Still accepted as the same declaration, and still returned in step with operating_is_remote while an operating address is on file.

operating_is_remote

Set profile.addresses.operating_is_remote (KYB) when the business has no office and the address it operates from is the residential address of a control person. Seismic adds a statement to that effect to the supplemental information document it sends to compliance review.

physical stays optional. Send it when the residence the business operates from is not the registered address already on the profile:

{
  "addresses": {
    "operating_is_remote": true,
    "physical": {
      "line1": "88 Cedar Ave",
      "city": "Austin",
      "state": "TX",
      "postal_code": "78701",
      "country": "US"
    }
  }
}

The flag and the operating address have to agree, in both directions. Only beneficial owners count — an associated_persons entry without the beneficial_owner role has no residence the business can be operating out of:

  • With the flag set and a physical address sent, that address must match the address of one of the profile's beneficial owners — otherwise submission fails with an other violation on addresses.physical.
  • When physical does match a beneficial owner's address, the flag must be set — otherwise submission fails with a not_in_allowed_set violation on addresses.operating_is_remote.

Addresses are compared as premises, not as strings: casing, extra whitespace and postal-code separators don't matter, but Ave and Avenue are different addresses.

The declaration also covers the company's proof of address: the beneficial owner whose residential address matches the operating address proves it with their own proof_of_address document, so no company-level one is required at submit. A company proof_of_address uploaded anyway is deduplicated by file name against that person's document, or kept as other with the description "Alternate proof of address for the company".

Addresses sent without either flag read as operating_is_remote: false, so existing payloads are unaffected.

Country codes

Every country-valued field takes an ISO-3166-1 alpha-2 code: two uppercase letters, such as SG, US, GB. Country names are rejected — "Singapore" fails validation, "SG" is what the field wants. The same rule covers nationality, citizenship, country_of_birth, country_of_residence, phone_country_code, gov_id_country, country_of_registration, regulated_authority_country, and the jurisdiction arrays.

City-states repeat the name across the address. city keeps the human-readable name ("Singapore"), country still takes the code ("SG"), and state is omitted because Singapore's address format has no state or region. Not every city-state drops state: Hong Kong's format includes an area, so HK addresses require one.

Correct:

{
  "line1": "1 Raffles Place",
  "city": "Singapore",
  "postal_code": "048616",
  "country": "SG"
}

Rejected:

{
  "line1": "1 Raffles Place",
  "city": "Singapore",
  "state": "Singapore",
  "postal_code": "048616",
  "country": "Singapore"
}

Phone numbers

Every profile phone (contact.phone, and phone on each associated person) is checked at submit in two steps:

  • Shape. E.164: +, the country calling code, then the national number, with no spaces or punctuation — 8–15 digits after the +.
  • Digits for the calling code. The number must fall in a real number range for its calling code, checked against published per-country numbering plans. Lengths vary by country and by line type, so there is no single digit count to aim for.

Two mistakes account for most rejections:

  • The national trunk prefix is kept. A leading 0 dialled inside the country is not part of the E.164 number: UK 07911 123456 is +447911123456, not +4407911123456. Italy is the exception — its leading 0 stays (+390212345678).
  • The calling code is typed twice. Singapore 8753 1018 is +6587531018, not +656587531018.

A number that fails either step is rejected with invalid_format on its field, and the message names the calling code. A calling code with no published numbering plan is checked for shape only.

TransliteratedAddress

Latin-1 form of an address whose canonical fields contain non-Latin-1 characters (Cyrillic, CJK, Arabic, etc.). Sanctions / PEP screening runs against Latin-only databases, so the romanized form is required alongside the original. All-or-nothing: when the canonical address triggers the requirement, every required canonical field needs a Latin counterpart. country is omitted. ISO-3166 codes are always Latin-1.

FieldTypeRequired at submitNotes
line1stringyesAt least 4 characters.
line2stringnoSupply it when canonical line2 is set.
citystringyes
statestringnoSupply it when canonical state is set.
postal_codestringconditionalSame rule as the canonical postal_code.

KycProfile

The unified individual-KYC profile body. Lives under profile on an individual customer envelope. Read it via GET /customers/:id/kyc/profile, write it via PUT /customers/:id/kyc/profile.

identity

FieldTypeRequired at submitNotes
first_name, last_namestringyes
middle_namestringno
transliterated_first_namestringconditionalLatin-1 romanization. Required when the canonical name contains non-Latin-1 characters.
transliterated_middle_namestringconditionalLatin-1 romanization, when canonical middle_name contains non-Latin-1 characters.
transliterated_last_namestringconditionalLatin-1 romanization, when canonical last_name contains non-Latin-1 characters.
date_of_birthstring (ISO-8601 date)yesYYYY-MM-DD.
nationalitystring (ISO-3166 α-2)noPassport country. Two-letter code, see Country codes.
citizenshipstring (ISO-3166 α-2)noMay equal nationality.
gender"male" | "female"noRequired before Seismic can provision a virtual account in some currencies.
country_of_birthstring (ISO-3166 α-2)noWhere the customer was born. Distinct from nationality and citizenship — a person can be born in a country whose passport and citizenship they do not hold.
country_of_residencestring (ISO-3166 α-2)yesOften equal to nationality. Drives the tax-id rule below and sanctions screening.
tax_identification_numberstringconditionalTax id issued by the country of residence (SSN/ITIN for US residents). This individual field is identity.tax_identification_number; associated persons use tax_id. Required when country_of_residence === "US".
social_profile_urlstring (URL)noLink to the customer's profile on LinkedIn, Facebook, Instagram or X. Corroborates the identity on the government ID during review. Optional today; see Social profile.

Social profile

identity.social_profile_url takes an http/https link to the customer's profile on one of four networks:

  • linkedin.com
  • facebook.com
  • instagram.com
  • x.com (twitter.com is accepted for links saved under the old domain)

Subdomains are fine, so https://www.linkedin.com/in/alice and https://m.facebook.com/alice both pass. A link to any other host is rejected at submit with a NotInAllowedSet violation on identity.social_profile_url, and a value that isn't a usable link is rejected as InvalidFormat.

The field is optional. Submissions that omit it succeed exactly as before. A future release will require it for customers whose government ID was issued outside the US, EU or Canada — that change will get its own changelog entry and advance notice before it takes effect.

addresses

FieldTypeRequired at submitNotes
residentialAddressyesWhere the customer lives. Must be a physical street address. A PO box is rejected at submit.
mailingAddressnoOptional separate mailing address. Defaults to residential when omitted. May be a PO box.

contact

FieldTypeRequired at submitNotes
emailstringyesPrimary contact.
phonestringyesE.164 required, valid for its calling code, e.g. +14155552671. See phone numbers.
phone_country_codestring (ISO-3166 α-2)yesCountry whose dialing code is on phone.

employment

FieldTypeRequired at submitNotes
employment_statusEmploymentStatusyes
employment_descriptionstringconditionalRequired when employment_status === "other". Free-form.
occupation_socstringyesThe individual's occupation, as a 6-digit SOC code (NN-NNNN) from the occupation codes catalog. A code outside the catalog is rejected.
employer_namestringno
EmploymentStatus

One of:

  • employee
  • self_employed
  • retired
  • unemployed
  • homemaker
  • student
  • other: set employment_description alongside.

risk

AML questionnaire. Self-attested.

FieldTypeRequired at submitNotes
primary_source_of_fundsSourceOfFundsyesWhere the funds that will be flowing through the platform originate from.
primary_source_of_funds_descriptionstringconditionalRequired when primary_source_of_funds === "other". Free-form.
source_of_wealthstringnoHow the individual has generally attained wealth — not necessarily the same as how transactions through the platform are funded. Send one of the SourceOfFunds values. Free text (max 256 characters) is accepted until November 1, 2026; from then it is required and must be one of those values.
account_purposeAccountPurposeyesRequired for every individual customer.
account_purpose_explanationstringconditionalRequired when account_purpose === "other".
acting_as_intermediarybooleannoWhether this entity sits between any payer and payee. This includes marketplaces and fintech companies, even non-custodial ones that are not in the flow of funds. Defaults to false.
pep_statusbooleannoPolitically Exposed Person, self-attested. Defaults to false. We record only the boolean, never the underlying role.
SourceOfFunds

Where the customer's funds come from. One of:

  • salary
  • savings
  • business_revenue
  • company_capital
  • investment_returns
  • inheritance
  • trust
  • gift
  • grant
  • sale_of_assets
  • real_estate
  • loan
  • private_capital
  • marital
  • winnings
  • other

On a business (KYB) profile, primary_source_of_funds_description is required whatever value is chosen. On an individual (KYC) profile, only other requires it.

AccountPurpose

Why the customer is opening this account. Every value is accepted for individual and business customers alike, but we recommend picking from the per-kind list below — a purpose outside its list can reach review as free text instead of a category, which clears slower. The hosted verification wizard offers exactly these, in this order; mirror it when you build your own form so a customer sees the same choices in the same order.

Recommended for a consumer (individual customer):

  1. salary_collections: receive my salary.
  2. personal_use: pay for personal expenses.
  3. remittances: make payments to friends or family abroad.
  4. purchase_goods_and_services: pay for goods and services.
  5. savings: store savings.
  6. investment: make investments.
  7. freelance_collections: receive my freelance payments.
  8. charitable_donations: make charitable donations.
  9. other: set account_purpose_explanation alongside.

Recommended for a business customer:

  1. purchase_goods_and_services: pay for goods and services.
  2. receive_payments_for_goods_and_services: receive payments for goods and services.
  3. investment: make investments.
  4. ecommerce_collections: accept retail e-commerce payments.
  5. charitable_donations: make or receive charitable donations.
  6. other: set account_purpose_explanation alongside.

Accepted, but not recommended for either kind:

  • crypto_investment: reviewed the same as investment. Send investment.
  • payroll: paying employees or contractors. Reviewed the same as purchase_goods_and_services. Send that instead.
  • business_operations: legacy. Accepted for existing integrations — submits as other with the purpose as account_purpose_explanation.
  • treasury_management: legacy. Same handling as business_operations.

volumes

Estimated transaction counts and exact USD figures. Nonnegative. 0 is valid.

FieldTypeRequired at submitNotes
usd_value_of_fiatnumberyesFiat activity per month, USD.
usd_value_of_cryptonumbernoCrypto activity per month, USD. Defaults to 0 when omitted.
monthly_depositsintegernoFiat deposit count per month.
monthly_withdrawalsintegernoFiat withdrawal count per month.
monthly_crypto_depositsintegernoCrypto deposit count per month. Defaults to 0 when omitted.
monthly_crypto_withdrawalsintegernoCrypto withdrawal count per month. Defaults to 0 when omitted.
monthly_investment_deposit_usdnumbernoInvestment deposit value per month, USD. Defaults to 0 when omitted.
monthly_investment_withdrawal_usdnumbernoInvestment withdrawal value per month, USD. Defaults to 0 when omitted.
monthly_crypto_investment_deposit_usdnumbernoCrypto investment deposit value per month, USD. Defaults to 0 when omitted.
monthly_crypto_investment_withdrawal_usdnumbernoCrypto investment withdrawal value per month, USD. Defaults to 0 when omitted.
expected_monthly_payments_usdnumbernoExact expected monthly USD payments. Defaults to usd_value_of_fiat when omitted.

jurisdictions

FieldTypeRequired at submitNotes
funds_send_receive_jurisdictionsarray of ISO-3166 α-2noCountries the user expects to send/receive funds to-from.
high_risk_activitiesarray of HighRiskActivityyesSelf-attested high-risk activities. Must be non-empty from 2026-09-14 — send ["none_of_the_above"] when none apply, so an unanswered question is never read as a negative answer.
vendors_and_counterpartiesarray of CounterpartyTypenoCounterparty types the user transacts with.
HighRiskActivity

One of:

  • adult_entertainment
  • gambling
  • marijuana
  • drugs
  • firearms
  • crypto_mixing: operating a crypto tumbler / mixer service.
  • money_services
  • lending_or_banking
  • foreign_exchange
  • hold_client_funds
  • investment_services
  • safe_deposit_box
  • tobacco
  • pharmaceuticals
  • third_party_payment_processing
  • none_of_the_above: explicit negative. Exclusive — sending it alongside any other value is rejected at submit. Send it on its own to disclose that none apply.
BusinessClassification

One of:

  • marketplace: gig platforms, booking platforms, delivery apps, app stores.
  • financial_services_provider: fintech companies, e.g. non-custodial neobanks, wallets, card programs, payment processors, remittance apps — including ones that never touch the flow of funds.
  • none_of_the_above: explicit negative. Exclusive — sending it alongside any other value is rejected at submit. Send it on its own to disclose that none apply.

marketplace and financial_services_provider each imply acting_as_intermediary. Either one must also upload a flow_of_funds and a Provider Attestation (licensed_vendors_attestation) document at submit, and must answer in_flow_of_funds (true or false) — see documents.

CounterpartyType

Who the customer expects to transact with. One of:

  • self_transactions
  • merchants_suppliers
  • customers
  • employees
  • contractors
  • friends
  • family

attestations

Submission-time attestations. Both must be true at submit (some hosted KYC flows collect them on the form instead, when that's the case, leave them as the default false and they'll be set when the customer agrees in-flow).

FieldTypeRequired at submitNotes
terms_and_conditions_acceptedbooleanyes (true)
information_attestedbooleanyes (true)

documents

Government-issued ID metadata + supporting documents. Bytes are uploaded separately via POST /customers/:id/kyc/documents. The profile carries document_id references.

FieldTypeRequired at submitNotes
government_issued_identificationGovernmentIdentificationyesAt least the front image is required.
supporting_documentsarray of SupportingDocumentRefyesRead-only. Derived from uploads through the documents endpoints; values sent in a profile PUT are ignored. Upload required evidence there, including selfie and proof of address when required at submit.
GovernmentIdentification
FieldTypeRequired at submitNotes
kindGovIdKindyes
numberstringyesDocument number.
countrystring (ISO-3166 α-2)yesIssuing country.
front_image_document_idstring (UUID)yesdocument_id for the front image, from POST /customers/:id/kyc/documents with the DocumentKind matching the ID type: passport for passports, identity_card_front for national IDs, or drivers_licence_front for driver's licenses.
back_image_document_idstring (UUID)conditionalRequired for two-sided IDs (driver's license and national ID). Upload the back under the matching *_back kind (e.g. identity_card_back). Absent for passports, which are single-sided.
issuance_datestring (ISO-8601 date)noWhen the document was issued (YYYY-MM-DD).
expiration_datestring (ISO-8601 date)noWhen the document expires (YYYY-MM-DD). Optional in general, but required before an AED account can be opened.
SupportingDocumentRef
FieldTypeRequired at submitNotes
kindstringyesOne of the DocumentKind slugs (bank_statement, proof_of_address, etc.).
document_idstring (UUID)yesdocument_id from a POST /customers/:id/kyc/documents upload.
GovIdKind

New submissions accept:

  • passport
  • drivers_license
  • national_id

Existing profile reads can also return legacy values:

  • residence_permit
  • voters_card
  • other

supplemental

Free-form entries for responding when review asks for more information — a text note or a supplemental document, each with a title and description. The section itself is optional at submit; the rules below apply to each entry sent. It is omitted from the response while empty, and profile saves are full-replace: a PUT /customers/:id/kyc/profile that omits supplemental clears the section, so echo the existing entries (with their ids) on every save they should survive.

FieldTypeRequired at submitNotes
idstring (UUID)no (server-assigned)Populated on read after the first save. Echo it back so the entry stays stable across saves.
kind"text" | "document"yesWhether the entry is a free-form note or references an uploaded document.
titlestringconditionalShort label for the entry. Required when kind === "text". A document entry needs a title or a description saying what the file is; with neither, submit reports supplemental[i].title.
descriptionstringconditionalThe note body. Required when kind === "text"; for a document entry, required unless title is set.
document_idstring (UUID)conditionalRequired when kind === "document". document_id from a POST /customers/:id/kyc/documents upload with kind=supplemental.

Example

A fully-populated profile body for an individual customer:

{
  "identity": {
    "first_name": "Alice",
    "middle_name": "Margaret",
    "last_name": "Liddell",
    "date_of_birth": "1985-06-15",
    "nationality": "US",
    "citizenship": "US",
    "gender": "female",
    "country_of_birth": "US",
    "country_of_residence": "US",
    "tax_identification_number": "123-45-6789",
    "social_profile_url": "https://www.linkedin.com/in/alice-liddell"
  },
  "addresses": {
    "residential": {
      "line1": "1 Wall St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10005",
      "country": "US"
    }
  },
  "contact": {
    "email": "alice@example.com",
    "phone": "+12025550100",
    "phone_country_code": "US"
  },
  "employment": {
    "employment_status": "employee",
    "occupation_soc": "15-1252",
    "employer_name": "Acme Inc."
  },
  "risk": {
    "primary_source_of_funds": "salary",
    "source_of_wealth": "savings",
    "account_purpose": "personal_use",
    "acting_as_intermediary": false,
    "pep_status": false
  },
  "volumes": {
    "usd_value_of_fiat": 120000,
    "usd_value_of_crypto": 25000,
    "monthly_deposits": 4,
    "monthly_withdrawals": 2,
    "monthly_crypto_deposits": 1,
    "monthly_crypto_withdrawals": 0,
    "monthly_investment_deposit_usd": 500,
    "monthly_investment_withdrawal_usd": 0,
    "monthly_crypto_investment_deposit_usd": 0,
    "monthly_crypto_investment_withdrawal_usd": 0
  },
  "jurisdictions": {
    "funds_send_receive_jurisdictions": [
      "US",
      "GB"
    ],
    "high_risk_activities": [
      "none_of_the_above"
    ],
    "vendors_and_counterparties": [
      "self_transactions",
      "merchants_suppliers"
    ]
  },
  "attestations": {
    "terms_and_conditions_accepted": true,
    "information_attested": true
  },
  "documents": {
    "government_issued_identification": {
      "kind": "passport",
      "number": "X12345678",
      "country": "US",
      "front_image_document_id": "8e3b…"
    },
    "supporting_documents": [
      {
        "kind": "selfie",
        "document_id": "c07a…"
      },
      {
        "kind": "proof_of_address",
        "document_id": "1f4d…"
      }
    ]
  },
  "supplemental": [
    {
      "id": "0e8b…",
      "kind": "text",
      "title": "Clarification on settlement volumes",
      "description": "Q3 volume increase reflects two new enterprise clients onboarded in July."
    },
    {
      "id": "7f1a…",
      "kind": "document",
      "title": "March bank statement",
      "description": "Statement covering the period referenced in the review.",
      "document_id": "b2c3…"
    }
  ]
}

KybProfile

The unified business-KYB profile body. Lives under profile on a business customer envelope. Read it via GET /customers/:id/kyc/profile, write it via PUT /customers/:id/kyc/profile.

The shape matches the org's own KybProfile one-for-one. Same sub-sections, same enums, same submit-time validation. The difference is who's being verified: the integrator's own KYB lives under /v0/org/kyb/*. This body verifies the integrator's end-customer businesses.

business

FieldTypeRequired at submitNotes
legal_namestringyesFormal entity name as registered.
trade_namestringno"Doing business as". Must differ from legal_name; omit it when the business has no DBA. When set, a dba_registration document is required at submit.
transliterated_legal_namestringconditionalLatin-1 romanization. Required when legal_name contains non-Latin-1 characters.
transliterated_trade_namestringnoLatin-1 romanization of trade_name.
entity_typeEntityTypeyes
corporate_entity_type_descriptionstringconditionalRequired when entity_type === "other" or entity_type === "dao". Free-form.
industrystringyesNAICS code, e.g. "425120". GET /industries lists the accepted set. Anything else is rejected as incomplete.
descriptionstringyesDescription of the business: what product or service it provides, who its customers are, how it makes money, and how funds move through it. At least 350 characters at submit — reviewers need real detail to clear an entity. A shorter one fails with a too_short violation. From 2026-11-01, at most 1,000 characters (too_long).
registration_numberstringyesGovernment-issued company id (UK Companies House, etc.).
tax_idstringyesEIN / equivalent.
country_of_registrationstring (ISO-3166 α-2)yesTwo-letter code: "US", "GB", etc. See Country codes.
state_of_incorporationstringconditionalRequired when country_of_registration === "US".
formation_datestring (ISO-8601 date)yesWhen the entity was formed.
websitestring (URL)conditionalPublic-facing URL. Omit it when the entity has no public website — then marketing_strategy, website_eta, and social_media_profile are required.
no_websitebooleannoThe entity has no public-facing website. Setting it clears website and makes marketing_strategy, website_eta, and social_media_profile required. Defaults to false.
marketing_strategystringconditionalHow the entity markets themselves to generate business. Required when the entity has no website; minimum 300 characters. Dropped on save when a website is given.
website_etastring (ISO-8601 date, or 0000-00-00)conditionalWhen the entity expects to publish a website, or 0000-00-00 when it does not intend to. Required when the entity has no website; a dated value must be in the future (violations[] reason: "out_of_range"). Dropped on save when a website is given.
social_media_profilestring (URL)conditionalA social media profile of the entity (preferred) or of one of its beneficial owners, standing in for the website it does not have. Required when the entity has no website. Dropped on save when a website is given.
target_customers_descriptionstringnoWho the business's target customers are: whether they are individuals or businesses, where they are located, and its top customer personas. Include the financial motivation for those customers to open accounts, and how they use them in practice — settlement methods, and inbound / outbound frequency and sizing. Seismic includes it in the supplemental information document it sends to compliance review.
pre_revenuebooleannoThe business has no revenue yet, so its proof of nature of business is alternative documentation of its preparations to operate rather than invoices or executed agreements. Seismic adds a statement to that effect to the supplemental information document it sends to compliance review. Defaults to false. Must be true exactly when volumes.estimated_annual_revenue_usd is 0. A pre-revenue business must also set operations.primary_source_of_funds to private_capital and upload a ubo_source_of_funds document.
is_daobooleannoWhether the entity is a DAO. Defaults to false.
EntityType

One of:

  • sole_proprietorship
  • llc
  • s_corporation
  • c_corporation
  • b_corporation
  • non_profit
  • partnership
  • limited_partnership
  • limited_liability_partnership
  • trust
  • dao
  • cooperative
  • other

addresses

FieldTypeRequired at submitNotes
registeredAddressyesLegal registered address.
physicalOperatingAddressnoOperating address if different. Defaults to registered when omitted. Note that the business' physical address cannot be a virtual address or an address of a registered agent.
operating_is_remotebooleannoDefaults to false. Set it when the business operates remotely and the address it operates from is a control person's residence rather than an office — see operating_is_remote.

contact

FieldTypeRequired at submitNotes
emailstringyesPrimary business contact.
phonestringyesE.164 required, valid for its calling code, e.g. +14155552671. See phone numbers.
phone_country_codestring (ISO-3166 α-2)yesCountry whose dialing code is on phone.

operations

Compliance / jurisdiction context.

FieldTypeRequired at submitNotes
business_jurisdictionsarray of ISO-3166 α-2noWhere the business operates.
funds_movement_jurisdictionsarray of ISO-3166 α-2noWhere funds will be sent/received. Defaults to business_jurisdictions on read when omitted.
primary_source_of_fundsSourceOfFundsyesThe business's historical source of funds: where its funds have come from to date.
primary_source_of_funds_descriptionstringyesFree-form detail on the business's historical source of funds. Required at submit whatever primary_source_of_funds is set to. From 2026-11-01, 200 to 1,000 characters (too_short / too_long).
source_of_wealthSourceOfFundsnoWhere the business's overall wealth came from — the net-worth question, as opposed to primary_source_of_funds, the business's historical source of funds: where its funds have come from to date. Takes the same options as primary_source_of_funds.
regulated_statusRegulatedStatusyes
regulated_activity_descriptionstringconditionalFree-form description of the licensed activity. All four regulated_* fields are required together when regulated_status is regulated, registered, or licensed, or when any one of them is set. All four are null together when the business conducts no regulated activity.
regulated_authority_countrystring (ISO-3166 α-2)conditionalIssuing authority's country.
regulated_authority_namestringconditionalName of the regulatory authority.
regulated_license_numberstringconditionalLicense number issued.
account_purposeAccountPurposeyesWhat the business plans to use the platform for.
account_purpose_explanationstringconditionalRequired when account_purpose === "other" or primary_source_of_funds === "other". From 2026-11-01, 200 to 1,000 characters when given (too_short / too_long). From 2026-11-14, required whatever account_purpose is.
registered_msbbooleannoWhether the business is registered as a money services business in any country. Defaults to false. Accepts the former conducts_money_services spelling on input.
registered_msb_descriptionstringconditionalRequired when registered_msb is true, and from 2026-11-01 also when in_flow_of_funds is true. Free-form. Accepts the former conducts_money_services_description spelling on input.
licensed_vendorsbooleannoWhether the business relies on licensed or regulated vendors as a core part of its operations. Defaults to false. When true, a Provider Attestation (licensed_vendors_attestation) document is required at submit (it is also required whenever business_classifications includes marketplace or financial_services_provider).
msb_compliance_screening_descriptionstringconditionalRequired when registered_msb is true, and from 2026-11-01 also when in_flow_of_funds is true. The compliance / AML screening program behind the registration. From 2026-11-01, at least 200 characters (too_short).
high_risk_activities_descriptionstringconditionalRequired when high_risk_activities names a real vertical. The business's involvement in the verticals it disclosed.
compliance_screening_explanationstringconditionalThe combined screening narrative. Normally derived — the two fields above are concatenated under MSB COMPLIANCE SCREENING DESCRIPTION / HIGH RISK ACTIVITY DESCRIPTION headers, since compliance receives one field. Set it directly to supply the whole narrative yourself; required that way when operates_in_prohibited_countries is true, which has no granular field. From 2026-11-01, the narrative, headers included, may be at most 1,000 characters; a longer one fails with a too_long violation on each field feeding it.
operates_in_prohibited_countriesbooleannoWhether the business operates in jurisdictions on the platform's prohibited list. Defaults to false.
high_risk_activitiesarray of HighRiskActivityyesSelf-attestations. Must be non-empty from 2026-09-14 — send ["none_of_the_above"] when none apply, so an unanswered question is never read as a negative answer.
has_complex_ownershipbooleannoSet true when the business has UBOs requiring beneficial-owner disclosure. Defaults to false.
business_classificationsarray of BusinessClassificationyesHow the business positions itself between payers and payees. Must be non-empty from 2026-09-14 — send ["none_of_the_above"] when none apply.
acting_as_intermediarybooleannoWhether this entity sits between any payer and payee. This includes marketplaces and fintech companies, even non-custodial ones that are not in the flow of funds. Defaults to false; implied by business_classifications.
in_flow_of_fundsbooleanconditionalWhether the business will at any point receive, hold, control, convert, or transmit customer funds, fiat or digital. Asked of marketplaces and financial services providers; Seismic includes the answer in the supplemental information document it sends to compliance review. Required at submit for marketplaces and financial services providers; false is an answer. From 2026-11-01, true requires registered_msb_description and msb_compliance_screening_description.
RegulatedStatus

One of:

  • regulated
  • registered: set the regulated_* fields alongside.
  • licensed
  • not_required

volumes

Estimated monthly transaction counts plus exact USD figures. Nonnegative. 0 is valid.

FieldTypeRequired at submitNotes
monthly_depositsintegernoFiat deposit count per month.
monthly_withdrawalsintegernoFiat withdrawal count per month.
monthly_crypto_depositsintegernoCrypto deposit count per month. Defaults to monthly_withdrawals when omitted and that count was given.
monthly_crypto_withdrawalsintegernoCrypto withdrawal count per month. Defaults to monthly_deposits when omitted and that count was given.
monthly_investment_deposit_usdnumbernoInvestment deposit value per month, USD.
monthly_investment_withdrawal_usdnumbernoInvestment withdrawal value per month, USD.
monthly_crypto_investment_deposit_usdnumbernoCrypto investment deposit value per month, USD.
monthly_crypto_investment_withdrawal_usdnumbernoCrypto investment withdrawal value per month, USD.
usd_value_of_fiatnumberyesFiat activity per month, USD.
usd_value_of_cryptonumbernoCrypto activity per month, USD. Defaults to usd_value_of_fiat when omitted.
expected_monthly_payments_usdnumbernoExpected total monthly payment volume, USD. Defaults to usd_value_of_fiat when omitted.
estimated_annual_revenue_usdnumberyesAnnual revenue, USD. Send 0 only for a business that has no revenue yet, and set business.pre_revenue to true alongside it.

counterparties

FieldTypeRequired at submit
counterpartiesarray of CounterpartyTypeno

attestations

Submission-time attestations. Both must be true at submit.

FieldTypeRequired at submitNotes
terms_and_conditions_acceptedbooleanyes (true)
information_attestedbooleanyes (true)

associated_persons

Add all beneficial owners (individuals with ≥25% ownership) and directors. Every business must have at least one beneficial owner and at least one director, even if it is the same person.

At submit time:

  • At least one entry is required.
  • At least one entry must include "beneficial_owner" in its roles array.
  • Every entry whose ownership_percent is 25 or more must include "beneficial_owner" in its roles array. Below 25 the role is optional.
  • At least one entry must include "control_person" or "officer" in its roles array.
  • At least one entry must include "authorized_signer" in its roles array.
  • From November 14, 2026, every entry must also include at least one of "control_person", "officer", "director", or "authorized_signer". An entry whose only role is "beneficial_owner" is rejected with a violation on associated_persons[i].roles.
  • Every entry must carry a full government-ID block (gov_id_kind, gov_id_number, gov_id_country, and gov_id_front_image_document_id), plus a selfie_document_id and a proof_of_address_document_id.
  • Sum of ownership_percent across all entries must be ≤ 100. Sums under 100 are accepted. The residual represents holders below the disclosure threshold (per FinCEN's CDD rule, only ≥25% holders need be individually identified). Values accept up to two decimal places, so fractional stakes (e.g. three owners at "33.33" each) sum to 100 instead of being forced to whole numbers that overshoot.
FieldTypeRequired at submitNotes
idstring (UUID)no (server-assigned)Populated on read after the first save. Required by POST /customers/:id/kyc/documents when uploading a per-person document.
customer_idstring (UUID)noAn individual customer in your organization that this person is. Links the two so Seismic verifies the human once instead of twice — see Linking a person to an individual customer.
first_name, last_namestringyes
middle_namestringno
transliterated_first_namestringconditionalLatin-1 romanization. Required when first_name contains non-Latin-1 characters.
transliterated_middle_namestringconditionalLatin-1 romanization. Required when middle_name is set and contains non-Latin-1 characters.
transliterated_last_namestringconditionalLatin-1 romanization. Required when last_name contains non-Latin-1 characters.
date_of_birthstring (ISO-8601 date)yes
emailstringyes
phonestringyesE.164 required, valid for its calling code, e.g. +14155552671. See phone numbers.
phone_country_codestring (ISO-3166 α-2)yesCountry whose dialing code is on phone.
addressAddressyesMailing address.
tax_idstringyesTax id issued by the country of residence (SSN for US residents).
nationalitystring (ISO-3166 α-2)noOptional for every role.
citizenshipstring (ISO-3166 α-2)noOptional for every role; may equal nationality.
gender"male" | "female"noRequired before Seismic can provision a virtual account in some currencies.
country_of_birthstring (ISO-3166 α-2)noWhere the person was born. Distinct from nationality and citizenship — a person can be born in a country whose passport and citizenship they do not hold.
source_of_wealthSourceOfWealthnoWhere this person's overall wealth came from. The net-worth question, as opposed to primary_source_of_funds, the business's historical source of funds: where its funds have come from to date.
previous_economic_activityarray of EconomicActivitynoWhat this person does for a living; more than one value can apply.
ownership_percentstring (decimal, 0–100)yesUp to two decimal places (e.g. "33.33"). Sum across all entries must be ≤ 100.
rolesarray of AssociatedPersonRoleyes (non-empty)At least one entry across all UBOs must include beneficial_owner, and so must every entry whose ownership_percent is 25 or more. From November 14, 2026, every entry must also include control_person, officer, director, or authorized_signer.
titlestringyesJob/role title (e.g. "CEO", "Director"). Required on every associated person, not only control persons and officers.
relationship_established_atstring (ISO-8601 date)yesWhen the person's relationship with the business began (YYYY-MM-DD).
gov_id_kindGovIdKindyesType of government-issued ID.
gov_id_numberstringyesThe ID number as printed on the document.
gov_id_countrystring (ISO-3166 α-2)yesIssuing country.
gov_id_front_image_document_idstring (UUID)yesdocument_id from a POST /customers/:id/kyc/documents upload with owner=person, person_id=<this id>, and the DocumentKind matching gov_id_kind: passport for passports, identity_card_front for national IDs, or drivers_licence_front for driver's licenses.
gov_id_back_image_document_idstring (UUID)conditionalSame shape as the front, uploaded under the matching *_back kind (e.g. drivers_licence_back). Required when gov_id_kind is drivers_license or national_id. Absent for passports.
gov_id_issuance_datestring (ISO-8601 date)noWhen the ID was issued (YYYY-MM-DD).
gov_id_expiration_datestring (ISO-8601 date)noWhen the ID expires (YYYY-MM-DD). Optional in general, but required before an AED account can be opened.
selfie_document_idstring (UUID)yesdocument_id from a POST /customers/:id/kyc/documents upload with owner=person, person_id=<this id>, kind=selfie.
proof_of_address_document_idstring (UUID)yesdocument_id from a POST /customers/:id/kyc/documents upload with owner=person, person_id=<this id>, kind=proof_of_address.
Linking a person to an individual customer

The same human is often both an individual customer of yours and a beneficial owner on a business customer's KYB profile. Set customer_id on the associated person to the individual customer's id and Seismic treats them as one person, reusing that customer's verification instead of putting them through it a second time.

Seismic accepts the link only when the two records identify the same person beyond doubt. The individual customer must belong to your organization and must match the submitted person on at least one of:

  • tax_id (compared with formatting removed, so 123-45-6789 and 123456789 agree),
  • email (case-insensitive), or
  • first_name and last_name (case-insensitive) and date_of_birth.

Anything short of that — an unknown id, a customer in another organization, or details that don't line up — rejects the whole profile save with a 422 kyb_profile_incomplete violation on associated_persons[i].customer_id.

Profile writes are full replacements, so a PUT that omits customer_id on a person removes any link that person had. Send the field on every save you want the link to survive.

The field applies to business customers only. Sending it on your organization's own KYB profile is rejected.

To find the customer to link rather than tracking the pairing yourself, ask GET /customers/:id/kyc/associated-persons/:person_id/link-suggestions — it returns the individual customers that already match this person under the rules above.

SourceOfWealth

One of:

  • salary
  • dividends
  • property_rental
  • investment
  • inheritance
  • gambling
  • donation

EconomicActivity

Multi-select. An entry can carry any combination.

  • employed
  • self_employed
  • student
  • gambler
  • pensioner
  • unemployed
AssociatedPersonRole

Multi-select. An entry can carry any combination.

  • beneficial_owner: ≥25% direct or indirect ownership.
  • control_person: exercises significant control / management.
  • officer: named officer (CEO, CFO, etc.). Sets title.
  • director: board member.
  • authorized_signer: empowered to sign on behalf of the entity.

supplemental

Free-form entries for responding when review asks for more information — a text note or a supplemental document, each with a title and description. The section itself is optional at submit; the rules below apply to each entry sent. It is omitted from the response while empty, and profile saves are full-replace: a PUT /customers/:id/kyc/profile that omits supplemental clears the section, so echo the existing entries (with their ids) on every save they should survive.

FieldTypeRequired at submitNotes
idstring (UUID)no (server-assigned)Populated on read after the first save. Echo it back so the entry stays stable across saves.
kind"text" | "document"yesWhether the entry is a free-form note or references an uploaded document.
titlestringconditionalShort label for the entry. Required when kind === "text". A document entry needs a title or a description saying what the file is; with neither, submit reports supplemental[i].title.
descriptionstringconditionalThe note body. Required when kind === "text"; for a document entry, required unless title is set.
document_idstring (UUID)conditionalRequired when kind === "document". document_id from a POST /customers/:id/kyc/documents upload with kind=supplemental.

documents

Business-level supporting documents (incorporation certificate, bank statement, ownership chart, etc.). Bytes are uploaded separately via POST /customers/:id/kyc/documents. Read this list to see what's been uploaded against the customer (the per-UBO government IDs are tracked under each associated_persons[].gov_id_*_image_document_id).

Each entry is a KybDocumentRef.

Required: business_formation, ownership_information, proof_of_nature_of_business, plus either a bank_statement or a ubo_bank_statement together with a proof_of_address. A business that sets operations.registered_msb must upload a flow_of_funds. A business whose operations.business_classifications includes marketplace or financial_services_provider must upload a flow_of_funds and a Provider Attestation (licensed_vendors_attestation). A business that sets business.pre_revenue must upload a ubo_source_of_funds. An org's own KYB additionally requires a Provider Attestation and a flow_of_funds whatever its answers say. See Required at submit for the full rules and the missing[] paths each gap reports.

Example

A fully-populated profile body for a business customer:

{
  "business": {
    "legal_name": "Acme Inc.",
    "trade_name": "Acme",
    "description": "Acme Inc. operates a marketplace connecting suppliers and merchants worldwide.",
    "entity_type": "c_corporation",
    "is_dao": false,
    "industry": "425120",
    "registration_number": "1234567",
    "tax_id": "82-1234567",
    "country_of_registration": "US",
    "state_of_incorporation": "DE",
    "formation_date": "2020-04-12",
    "website": "https://acme.example"
  },
  "addresses": {
    "registered": {
      "line1": "1 Wall St",
      "city": "New York",
      "state": "NY",
      "postal_code": "10005",
      "country": "US"
    }
  },
  "contact": {
    "email": "ops@acme.com",
    "phone": "+12025550100",
    "phone_country_code": "US"
  },
  "operations": {
    "business_jurisdictions": [
      "US"
    ],
    "funds_movement_jurisdictions": [
      "US",
      "GB"
    ],
    "primary_source_of_funds": "company_capital",
    "regulated_status": "not_required",
    "account_purpose": "purchase_goods_and_services",
    "registered_msb": false,
    "licensed_vendors": false,
    "operates_in_prohibited_countries": false,
    "high_risk_activities": [
      "none_of_the_above"
    ],
    "has_complex_ownership": false,
    "business_classifications": [
      "none_of_the_above"
    ],
    "acting_as_intermediary": false
  },
  "volumes": {
    "monthly_deposits": 35,
    "monthly_withdrawals": 30,
    "monthly_investment_deposit_usd": 0,
    "monthly_investment_withdrawal_usd": 0,
    "monthly_crypto_investment_deposit_usd": 0,
    "monthly_crypto_investment_withdrawal_usd": 0,
    "usd_value_of_fiat": 5000000,
    "usd_value_of_crypto": 0,
    "expected_monthly_payments_usd": 250000,
    "estimated_annual_revenue_usd": 5000000
  },
  "counterparties": {
    "counterparties": [
      "customers",
      "merchants_suppliers"
    ]
  },
  "attestations": {
    "terms_and_conditions_accepted": true,
    "information_attested": true
  },
  "associated_persons": [
    {
      "id": "5e3a…",
      "first_name": "Alice",
      "last_name": "Liddell",
      "date_of_birth": "1985-06-15",
      "email": "alice@acme.com",
      "phone": "+12025550100",
      "phone_country_code": "US",
      "address": {
        "line1": "1 Wall St",
        "city": "New York",
        "state": "NY",
        "postal_code": "10005",
        "country": "US"
      },
      "tax_id": "123-45-6789",
      "nationality": "US",
      "citizenship": "US",
      "gender": "female",
      "country_of_birth": "US",
      "source_of_wealth": "salary",
      "previous_economic_activity": [
        "employed"
      ],
      "ownership_percent": "100",
      "roles": [
        "beneficial_owner",
        "officer",
        "director",
        "authorized_signer"
      ],
      "title": "CEO",
      "relationship_established_at": "2020-04-12",
      "gov_id_kind": "passport",
      "gov_id_number": "X12345678",
      "gov_id_country": "US",
      "gov_id_front_image_document_id": "8e3b…",
      "selfie_document_id": "c07a…",
      "proof_of_address_document_id": "b921…"
    }
  ],
  "supplemental": [
    {
      "id": "0e8b…",
      "kind": "text",
      "title": "Clarification on settlement volumes",
      "description": "Q3 volume increase reflects two new enterprise clients onboarded in July."
    },
    {
      "id": "7f1a…",
      "kind": "document",
      "title": "March bank statement",
      "description": "Statement covering the period referenced in the review.",
      "document_id": "b2c3…"
    }
  ],
  "documents": [
    {
      "document_id": "1f4d…",
      "kind": "articles_of_association",
      "filename": "acme-articles.pdf",
      "content_type": "application/pdf",
      "size_bytes": 184213,
      "uploaded_at": "2026-05-10T20:14:21.045Z"
    }
  ]
}

KyStatus

The unified verification lifecycle, used for both kyc_status (on individuals) and kyb_status (on businesses).

ValueNotes
draftCustomer created and editable. Not yet submitted for verification.
submittedProfile received and under Seismic's review before verification begins. No hosted link yet.
under_reviewVerification in progress.
approvedVerification passed. Account creation now callable. Editing the profile and resubmitting with the explicit ?resubmit_approved=1 opt-in re-verifies the updated details, and may move the status back into review until the re-check completes.
rejectedThe submission was rejected, by Seismic's review or during verification. rejection_reason carries the human-readable explanation. The customer can correct the profile and resubmit.
terminally_rejectedA non-correctable decision. Unlike rejected, the profile is locked and the submit route refuses to re-drive the customer.
pausedSeismic has placed a compliance hold on the customer. They cannot transact, and resubmitting the profile does not lift it. The hold is reversible — the status moves on once it is lifted.
unknownVerification backend returned a status we don't recognize.

CustomerState

Polymorphic state envelope returned by POST /customers/:id/kyc/submit, POST /customers/:id/kyc/sync-approvals, GET /customers/:id/kyc/state, and POST /customers/:id/kyc/resync. The type discriminator picks the field names inside state (kyc_status / kyc_link for individuals, kyb_status / kyb_link for businesses). The rest of the field set is identical.

FieldTypeNotes
type"individual" | "business"Matches the customer's type. Picks the shape of state.
stateobject (see below)Nested state body.

state (KYC variant, when type === "individual"):

FieldTypeNotes
kyc_statusKyStatusRolled-up status. See KyStatus for values.
kyc_linkobject | nullA separate verification redirect of the form { url, expires_at }, distinct from the Seismic-hosted kyc_link on the Customer envelope. Present only when the verification flow requires an external redirect (e.g. a hosted document-capture step). null otherwise. expires_at is an RFC-3339 timestamp.
missing_fieldsarray of stringDotted paths into the profile that need to be filled. Empty after a clean submit.
last_synced_atstringRFC-3339 timestamp, millisecond precision, when the cached state was last reconciled.
rejection_reasonstring | nullHuman-readable, when the rolled-up status is rejected.
pending_rfibooleanAn open request for information is outstanding, independent of kyc_status. See when requests are visible for which statuses it can be true at and what clears it.
last_submitted_atstring (ISO-8601) | nullWhen the profile was last filed for verification. null until the first submission. Moves on every resubmission, which the status can't show on its own — a resubmit returns to the review it left.

state (KYB variant, when type === "business"): same fields with kyb_status and kyb_link substituted for the kyc_* names.

Account

A working account. Embedded on the response to the four POST /customers/:id/accounts/{kind}/{origin} endpoints (under account, when one exists yet), returned by GET /accounts/:id, the per-kind GETs (fiat, crypto), and GET /accounts. Also embedded in quote responses when a leg resolves from an attached account.

Account normally represents a usable account. The creating lifecycle (still-pending, partial failures, retries) lives on the separate AccountCreationRequest resource, but so callers can watch one stream instead of two, a virtual account that Seismic hasn't finished provisioning (or couldn't provision) also appears here with status: "pending" / "failed".

kind + shape together determine the layout of details: kind=fiat, shape=us → details is a UsBankFiatAccount. kind=crypto, shape=evm → details is a CryptoAccount. Narrow on kind first, then narrow details structurally.

FieldTypeNotes
idstringOur UUID.
customer_idstringOur customer UUID.
kind"fiat" | "crypto"Top-level discriminator. Picks the layout of details.
shapeFiatShape | CryptoShapeRefines within kind. Disjoint variant sets, "us"/"uk"/"iban"/… vs "evm", ….
origin"external" | "virtual"external, caller-attached, account belongs to the customer at their own bank / wallet. virtual, provisioned by Seismic.
currencystringISO-4217 or stablecoin symbol ("USD", "USDC", …). One currency per account today.
railsstring[]["ach", "wire"], ["sepa", "swift"], ["base"], …. Plural, a US bank settles over multiple rails. Crypto returns a one-element array (one wallet = one chain).
status"pending" | "active" | "failed" | "closed"active is the normal state. closed means the account has been retired: see Closed accounts. pending and failed only appear on virtual accounts: pending while Seismic is still provisioning, failed if provisioning couldn't complete and the account never became usable. For crypto, the entry is sourced from the underlying AccountCreationRequest and details.address is omitted. For fiat, the account exists from creation but details is absent until provisioning completes — there are no payable coordinates to show while pending.
balancestring?Funds credited to the account, in currency major units, as of balance_as_of. The stored figure is kept in sync as funds move. Present on virtual accounts: single-account reads refresh a never-synced balance at request time, while list reads may omit it until the first sync lands. Always absent on external accounts. See GET /accounts/:id/balance.
available_balancestring?Portion of balance spendable right now (total minus holds/pending). Absent when the distinction doesn't exist.
balance_as_ofstring?ISO-8601. When Seismic last refreshed balance.
created_atstringISO-8601.
updated_atstringISO-8601.
detailsFiatAccount | CryptoAccount?Per-shape detail block. Layout is determined by kind + shape. Absent on a virtual bank account until its identifiers are issued (pending / failed), and absent when status is "closed" — a retired account publishes no deposit instructions. See Closed accounts. Always present once active, and on external accounts.
liquidationobject?Present on virtual fiat accounts that auto-liquidate, whether the target was set at creation or added later. { account_id, address, currency } names the crypto account incoming fiat is auto-converted and settled to. developer_fee_bps (number, optional) echoes the fee in basis points (100 = 1%). can_turn_off (boolean) says whether DELETE /accounts/:id/liquidation will be accepted. See auto-liquidation.
can_enable_liquidationboolean?Whether auto-liquidation can be turned on for this account via PUT /accounts/:id/liquidation. Present only on virtual bank accounts that don't already auto-liquidate; false or absent means a target can only be attached at creation.

Closed accounts

A closed account has been retired. It can no longer receive deposits, and it carries no details — the field is absent, not blanked, so there is nothing to mistake for a live identifier. Any account number, IBAN or wallet address you previously showed for it must not be used again.

Closing is not deleting. A closed account keeps its place in GET /accounts and GET /accounts/:id, and its payments, deposits and orders stay queryable, so history stays intact. DELETE /accounts/:id is the destructive counterpart: a deleted account disappears from both endpoints.

Closure is announced on the account.updated webhook. The embedded account in that event reads status: "closed" and carries no details, so the event itself is enough to retire the account in your own systems — no follow-up read required.

To list them, filter on status=closed.

FiatShape

Discriminator for the fiat-side details block. Lists only the shapes wired end-to-end today, more land as Seismic adds settlement support.

"us" | "uk" | "iban" | "swift" | "cn_cnaps" | "hk_fps" | "sg_fast" | "in_ifsc" | "mx_clabe" | "ar_cbu" | "ph_bank" | "thb_bank" | "idr_bank" | "ca_eft" | "pk_iban" | "ng_bank" | "br_pix" | "br_bank" | "au_bsb" | "co_bank"

CryptoShape

Discriminator for the crypto-side details block. Lists only the shapes wired end-to-end today, more land as Seismic adds settlement support.

"evm" | "sol"

External crypto accounts accept evm and sol; the shape is inferred from the selected rail when omitted.

FiatAccount

Account.details (and AccountCreationRequest.details) when kind === "fiat". One of the concrete wired shapes, keyed by Account.shape. Narrow structurally on the present field set, "routing_number" in account.details selects the US-bank variant.

The request-side counterparts live on POST /customers/:id/accounts/fiat/external. Fiat external create accepts the bank-identifier fields under details and the legal owner under top-level account_holder. Response details includes account_holder_name derived from that holder block where applicable.

On a virtual account, account_holder_name starts as the account holder's name and is replaced by the beneficiary name the issuing bank prints once the account is active. Quote the active account's account_holder_name in payment instructions.

shape: "us"

FieldTypeNotes
account_numberstringBank account number.
routing_numberstringThe account's ABA routing number: the one quoted for an ACH credit when the account has one, otherwise the one quoted for a Fedwire credit. Always present, whatever the account settles over; the per-rail fields below say which credits each number may actually be quoted for.
ach_routing_numberstring?ABA routing number to quote for an ACH credit. Absent when the account does not settle over ACH.
fedwire_routing_numberstring?ABA routing number to quote for a Fedwire credit. A bank that publishes a separate wire ABA reports it here; otherwise an account that settles over wire routes it off the same nine digits as ach_routing_number and reports those. Absent on an account that does not settle over wire.
rtp_routing_numberstring?ABA routing number to quote for an instant (RTP) credit, when the issuing bank publishes one distinct from ach_routing_number. Absent otherwise.
bicstring?BIC to quote for an inbound international wire, alongside swift_account_number. Absent when the account is reachable domestically only.
swift_account_numberstring?The account number a foreign sender quotes for an international wire. Distinct from account_number, which is the domestic one: the payment is often received through a correspondent, so this can be an IBAN at another bank. Absent when the account is reachable domestically only.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "uk"

FieldTypeNotes
sort_codestring6-digit UK sort code.
account_numberstringUK domestic account number.
ibanstring?Optional cross-border IBAN form.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "swift"

FieldTypeNotes
bicstringBIC / SWIFT code.
account_numberstringIBAN or domestic account number.
phonestring?Holder contact phone, when supplied.
tax_numberstring?Holder tax identification number, when supplied.
bank_namestringBank display/routing name.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "iban"

FieldTypeNotes
account_numberstringThe IBAN string.
bicstring?BIC to quote for an inbound international wire, alongside swift_account_number. Absent when the account is reachable domestically only.
swift_account_numberstring?The account number a foreign sender quotes for an international wire. Distinct from account_number, which is the domestic one: the payment is often received through a correspondent, so this can be an IBAN at another bank. Absent when the account is reachable domestically only.
bank_codestring?Domestic bank code (e.g. Swedish clearing number), when supplied.
phonestring?Holder contact phone, when supplied.
id_numberstring?Holder government ID number, when supplied. Individuals only.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "cn_cnaps"

FieldTypeNotes
account_numberstringChinese domestic bank account number.
cnaps_codestringCNAPS bank / branch routing code.
id_numberstringHolder tax / government ID number.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
bank_namestring?Display name of the bank, when known.
branch_namestring?Destination bank branch name (Hanzi), when supplied. Businesses only.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "hk_fps"

FieldTypeNotes
account_numberstringHong Kong destination account number.
bicstring?ISO 9362 BIC / SWIFT code of the destination bank — settlement routes on it. Absent only on accounts registered before it was collected.
bank_namestring?Display name of the bank, when supplied.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
date_of_incorporationstring?Incorporation date (YYYY-MM-DD), when supplied. Businesses only.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "sg_fast"

FieldTypeNotes
account_numberstringSingapore destination account number.
bank_namestringBank display/routing name.
phonestringHolder contact phone for the corridor.
id_numberstring?Holder government ID number, when supplied. Individuals only.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number (e.g. UEN), when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
relationship_to_debtorstring?Holder's relationship to the customer as a fixed 4-letter code, when supplied.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "in_ifsc"

FieldTypeNotes
ifscstringIFSC code (e.g. HDFC0001234).
account_numberstringIndian domestic account number.
phonestring?Holder contact phone, when supplied.
id_numberstring?Holder government ID number, when supplied. Individuals only.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
relationship_to_debtorstring?Holder's relationship to the customer as a fixed 4-letter code, when supplied.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "mx_clabe"

FieldTypeNotes
clabestring18-digit CLABE.
tax_numberstring?Holder tax id (RFC), when supplied.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "ar_cbu"

FieldTypeNotes
cbustring22-digit CBU.
aliasstring?CBU alias, when set.
tax_numberstringHolder CUIT.
phonestringHolder contact phone.
id_numberstring?Holder government ID number, when supplied. Individuals only.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
bank_namestringDisplay name of the bank.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "ph_bank"

FieldTypeNotes
account_numberstringPhilippine domestic account number.
bank_namestringDisplay name of the bank.
phonestring?Holder contact phone, when supplied.
registration_numberstring?Business registration number, when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
date_of_incorporationstring?Incorporation date (YYYY-MM-DD), when supplied. Businesses only.
relationship_to_debtorstring?Holder's relationship to the customer as a fixed 4-letter code, when supplied.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "thb_bank"

FieldTypeNotes
account_numberstringThai domestic account number.
bank_namestringDisplay name of the bank.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "idr_bank"

FieldTypeNotes
account_numberstringIndonesian domestic account number.
bank_namestringDisplay name of the bank.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "ca_eft"

FieldTypeNotes
institution_numberstring3-digit bank identifier.
transit_numberstring5-digit branch identifier.
account_numberstringCanadian domestic account number.
bank_namestringName of the destination bank.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "pk_iban"

FieldTypeNotes
ibanstringPakistan IBAN (24 chars).
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "ng_bank"

FieldTypeNotes
account_numberstringNUBAN account number (10 digits).
bank_codestringNumeric bank code, the routing key.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "br_pix"

FieldTypeNotes
pix_keystringThe PIX key.
pix_key_typestringcpf, cnpj, email, phone, or evp.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "br_bank"

FieldTypeNotes
bank_codestringCOMPE or ISPB bank code.
agencystringBranch code, optionally with a check digit.
account_numberstringBrazilian domestic account number.
account_subtypestringcc (checking) or pp (savings).
tax_numberstring?Holder CPF or CNPJ, when known.
phonestring?Holder contact phone, when supplied.
id_numberstring?Holder government ID number, when supplied. Individuals only.
id_typestring?Kind of ID id_number carries, when supplied. Individuals only.
registration_numberstring?Business registration number (e.g. CNPJ), when supplied. Businesses only.
registration_typestring?Kind of registration registration_number carries, when supplied. Businesses only.
bank_namestring?Display name of the bank, when known.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "au_bsb"

FieldTypeNotes
bsbstring6-digit Bank-State-Branch code.
account_numberstringAustralian domestic account number.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

shape: "co_bank"

FieldTypeNotes
bank_codestringBank code as published by the Colombian banking association.
account_numberstringColombian domestic account number.
account_typestringCHECKING or SAVINGS.
id_typestringKind of identity document id_number carries: CC, CE, NIT, PASS or PEP.
id_numberstringThe holder's identity document number.
account_holder_namestringName on the account.
bank_addressAddressMailing address registered with the bank.

CryptoAccount

Account.details (and AccountCreationRequest.details) when kind === "crypto". Same shape on the request side (POST /customers/:id/accounts/crypto/external) for origin: "external".

FieldTypeNotes
addressstring (optional)On-chain wallet address (EVM checksum, …). Omitted on a virtual crypto account while Account.status === "pending": Seismic is still provisioning the wallet. The field appears once provisioning completes. Also omitted when Account.status === "failed", where no address is coming.

AccountCreationRequest

Returned by the four POST /customers/:id/accounts/{kind}/{origin} endpoints (under request), GET /customers/:id/accounts/requests/:id, and the idempotency-key lookup. Carries the lifecycle of the creation, distinct from the Account it produces, which only exists once Seismic has finished registering / provisioning.

details mirrors the materialized Account.details. For origin: "external", details is always set from the caller-supplied bank / wallet info. Fiat responses add account_holder_name from the top-level account_holder block where applicable. For origin: "virtual", details is absent until provisioning completes. Callers can still derive the eventual layout from kind + shape.

FieldTypeNotes
idstringOur UUID for the creation request.
customer_idstringThe customer this request creates an account for.
kind"fiat" | "crypto"
shapeFiatShape | CryptoShape
origin"external" | "virtual"
currencystringAs supplied on (or inferred for) the request body.
railsstring[]Inferred for fiat (per-currency defaults today). Single-element for crypto (the one rail the wallet lives on).
status"pending" | "completed" | "failed"pending while Seismic is still registering / provisioning. completed once the registration succeeds and the Account row exists. failed only if Seismic couldn't register the account.
idempotency_keystringThe key the request was created with (caller-supplied or server-minted).
account_idstring?The id of the materialized Account once one exists. Populated synchronously for origin: "external". For virtual it lands once provisioning completes.
detailsFiatAccount | CryptoAccount?Caller-echoed (external) or populated by Seismic once provisioning completes (virtual). Absent until populated.
created_atstringISO-8601.
updated_atstringISO-8601.