POST /customers/:id/accounts/crypto/external
Register a wallet the customer already controls. Synchronous: caller supplies the on-chain address, so the Account materializes at request time and is returned on account.
Shared semantics (idempotency header, response envelope, error codes) live on the create-account index.
Uniqueness
A wallet registers once per customer per currency and network. Registering the same address + currency + rail again while the account is live returns a 400 naming it — addresses compare case-insensitively, so checksum casing makes no difference. The same wallet on a different network, or holding a different currency, is a distinct account.
Registering one you deleted restores it: the original id comes back and an account.created webhook is emitted. See getting a deleted account back.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
address | string | yes | On-chain wallet address. Validated against the chosen shape: EVM is ^0x[0-9a-fA-F]{40}$, and must look like a real wallet — placeholder, burn and patterned addresses are refused. Solana addresses must decode to a nonzero 32-byte Base58 public key; casing is significant. |
shape | CryptoShape | no | Inferred from rail when omitted ("evm" or "sol"). If supplied, must match the rail. |
rail | string | number | yes | Currency-or-rail reference. By name ("ethereum", "base", …) or numeric id. Must be a supported EVM or Solana rail. |
currency | string | number | yes | Currency the wallet holds ("USDC", "USDT", …). Must be settleable on the chosen rail (per currency_rails). |
account_holder | AccountHolderInput | no | Legal owner of the wallet. Omit it and Seismic derives the holder from the customer's own KYB/KYC profile. Supply it to register a wallet owned by a third party. Its industry may be any code GET /v0/industries lists. |
Headers
| Header | Value |
|---|---|
Idempotency-Key | Optional, up to 256 characters. Re-POSTing the same (org, key) returns the existing creation request unchanged. |
Response 200
{
"request": {
"id": "req_…",
"customer_id": "2f10…",
"kind": "crypto",
"shape": "evm",
"origin": "external",
"currency": "USDC",
"rails": ["ethereum"],
"status": "completed",
"idempotency_key": "abc-123",
"account_id": "acct_…",
"details": {
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f8b840"
},
"created_at": "2026-05-20T19:45:00Z",
"updated_at": "2026-05-20T19:45:00Z"
},
"account": {
"id": "acct_…",
"customer_id": "2f10…",
"kind": "crypto",
"shape": "evm",
"origin": "external",
"currency": "USDC",
"rails": ["ethereum"],
"status": "active",
"created_at": "2026-05-20T19:45:00Z",
"updated_at": "2026-05-20T19:45:00Z",
"details": {
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f8b840"
}
}
}Errors
- 400 InvalidAccountFields
address: not a valid EVM address, or not a usable wallet: a placeholder or burn address (0x0000…0000,0x000…dEaD,0x000…deadbeef), a single repeated digit (0x1111…1111), or a repeating pattern (0x1234567890repeated). Real addresses, including vanity ones with long runs of leading zeros, are unaffected. - 400 InvalidAccountFields
address: not a valid 32-byte Base58 Solana public key, or the all-zero system address. - 400 InvalidAccountFields
shape: does not match the selected rail. - 400 InvalidAccountFields
rail: rail isn't supported, isn't settleable for the chosen currency, or doesn't match the requested shape. - 400 InvalidAccountFields
currency: currency isn't a stablecoin / crypto kind. - 400 InvalidRequest
account_holder.address.postal_code: the postal code doesn't match the format used by itscountry. Raised for a postal code taken from the customer's profile too, whenaccount_holderis omitted. - 404: unknown currency or rail.
Example
The customer owns the wallet — account_holder is omitted and derived from their KYB/KYC profile:
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/crypto/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f8b840",
"rail": "ethereum",
"currency": "USDC"
}'To register a wallet owned by a third party, pass account_holder explicitly:
curl -X POST "$SEISMIC_ORCHESTRATION_URL/v0/customers/2f10…/accounts/crypto/external" \
-H "Api-Key: $SEISMIC_ORCHESTRATION_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"address": "0x742d35Cc6634C0532925a3b844Bc9e7595f8b840",
"rail": "ethereum",
"currency": "USDC",
"account_holder": {
"type": "individual",
"first_name": "Alice",
"last_name": "Walker",
"address": {
"country": "US"
},
"is_third_party": true
}
}'Example: external Solana wallet
Omit shape to infer sol from the rail. The returned account preserves the address exactly, including its case.
{
"currency": "USDC",
"rail": "solana",
"address": "7YttLkHDoNj9wyDur5A7eD3k1ySG5NCjc1QpNSUGpEGj"
}