Create Blockwyre Account
Overview
Every account you onboard starts as a customer of your workspace. v3 calls an account a customer (cst_…); v2 called it an account. You create the customer first, then verify it: an individual through KYC, a business through KYB. The same endpoint creates both kinds; customer_type decides which.
Before you start
- A workspace-scoped API key. Creating and listing customers is the workspace's own operation: it takes a workspace-scoped key (no
accountIdclaim). An account-scoped key is refused with401. See Key types and permissions. - Signed requests. Every request carries
Authorization: APIKey <signed JWT>; how to build it is in the Authentication guide. - The base URL of the environment you are calling: see Environments. Sandbox keys work only against the sandbox API, production keys only against production.
Create the customer
Endpoint: POST /v3/customers (reference)
Headers
| Header | Description |
|---|---|
Authorization | Required. APIKey <signed JWT>, signed with a workspace-scoped key. |
Idempotency-Key | Required, for every caller. One key per customer you intend to create: any printable-ASCII string of 1 to 255 characters (a UUID is recommended). Send the same key again on every retry of that same creation. |
Content-Type | application/json |
Request body
| Field | Type | Description |
|---|---|---|
customer_type | string | Required. individual or business. |
name | string | Required. 3 to 255 characters, surrounding spaces trimmed. The person's full name, or the business's legal name. |
email | string | Required. A valid email, at most 255 characters, not used by another customer of the workspace. |
v3 does not take your own reference or a pre-assigned id: store the id it returns. The applicant's first and last names go on the KYC record, not on the customer.
Individual customer
Request:
POST /v3/customers
Authorization: APIKey <signed JWT>
Idempotency-Key: 5b0f1f2e-8f0a-4c4b-9d3e-1f6c2a7b9e10
Content-Type: application/json
{
"customer_type": "individual",
"name": "Samantha Reyes",
"email": "samantha@example.com"
}
Response (200 OK):
{
"id": "cst_01k8x40x9gfx6sv8a99hswy9bd",
"reference": "019a3a40-7530-7f4d-9da1-494c73cf256d",
"name": "Samantha Reyes",
"email": "samantha@example.com",
"customer_type": "individual",
"status": "pending",
"verification_status": "incomplete",
"created_at": "2025-10-31T12:31:34Z",
"updated_at": "2025-10-31T12:31:34Z"
}
Business customer
Request body:
{
"customer_type": "business",
"name": "Northwind Traders LLC",
"email": "finance@northwind.example.com"
}
Response (200 OK):
{
"id": "cst_01k8x404w8ezyts68ghqdnpqxb",
"reference": "019a3a40-1388-77fd-ac99-108ddb5b5fab",
"name": "Northwind Traders LLC",
"email": "finance@northwind.example.com",
"customer_type": "business",
"status": "pending",
"verification_status": "incomplete",
"created_at": "2025-10-31T12:31:09Z",
"updated_at": "2025-10-31T12:31:09Z"
}
reference is the UUID form of id.
Retrying safely
A network error or a timeout leaves you not knowing whether the customer was created. Send the request again, unchanged, with the same Idempotency-Key:
| What happens | Answer |
|---|---|
| The first request finished, less than 24 hours ago | Its response again, with Idempotency-Replayed: true. No second customer is created. |
| The first request is still running | 409 idempotency_in_progress, with Retry-After: wait that many seconds and retry with the same key. |
| The same key with a different body | 422 idempotency_key_conflict. Use a new key for a different customer. |
| The same key more than 24 hours after the first request | The key has been forgotten: the request runs as a new one, so a customer it already created answers 409 customer_email_exists. |
No Idempotency-Key header, or an empty one | 400 idempotency_key_required. |
A 2xx or 4xx answer is stored and replayed; a 5xx is not, so retrying after one runs the request again. More in Safe retries.
Errors
Errors answer {"code": <status>, "message": "<code>"} (see Errors).
| Status | message | What to do |
|---|---|---|
400 | invalid_customer_name | Send a name of 3 to 255 characters. |
400 | invalid_email | Send an email of at most 255 characters that reads as an address. |
400 | failed to parse request | Send valid JSON, with customer_type individual or business. |
400 | idempotency_key_required / idempotency_key_invalid | Send an Idempotency-Key of 1 to 255 printable-ASCII characters. |
401 | unauthorized | Check the signature and claims, and that the key is workspace-scoped. |
409 | customer_email_exists | A customer of this workspace already has this email. Look it up with GET /v3/customers?q=<email>. |
409 | idempotency_in_progress | Retry after Retry-After seconds, with the same key. |
422 | Validation failed | A required field is missing or email is not an email; details names the field. |
422 | idempotency_key_conflict | The key was already used for another request. |
Customer statuses
A customer carries two statuses.
status, the account's lifecycle:
status | Means |
|---|---|
pending | Created, not verified yet. This is where every customer starts. |
active | Verified: an approved KYC (individual) or KYB (business) makes the customer active. |
closed | Closed. |
verification_status, where its verification stands (KYC for an individual, KYB for a business):
verification_status | Means |
|---|---|
incomplete | No verification record yet, or a record that is not under review: sent back for changes (needs_update), or a business record ready_for_review. |
pending | A record is open (pending) or under review (in_review). |
approved | Verified. |
failed | The verification was rejected. |
A customer can also carry blocked_at or frozen_at (no outgoing transactions) when BlockWyre or your workspace has blocked or frozen it.
Finding customers
| Endpoint | Use |
|---|---|
GET /v3/customers | The workspace's customers, a page at a time. Filter with q (name, email, reference or id), customer_type, verification_status, created_at_gte, created_at_lt; order with sort (e.g. sort=-created_at,name). limit defaults to 25 and is capped at 100. |
GET /v3/customers/{customer_id} | One customer, by its cst_… id. |
Both take a workspace-scoped key, like the create.
Next steps
v2 (deprecated)
POST /api/v2/accounts, GET /api/v2/accounts and GET /api/v2/accounts/{id} still work while integrations move, but they are deprecated: see Create Account, List Accounts and Get Account. The v2 create takes no Idempotency-Key, so a retry can create the account twice.
Support and Resources
If you need assistance or have any questions, our support team is here to help. You can contact our support team at support@blockwyre.com.
Stay Updated
Stay up-to-date with the latest news, updates, and features from BlockWyre by following us on social media:
- Instagram: BlockWyre Instagram
- Twitter: BlockWyre Twitter
- Facebook: BlockWyre Facebook
- LinkedIn: BlockWyre LinkedIn
We are excited to have you on board and look forward to seeing how you leverage BlockWyre's powerful tools to enhance your financial operations. Happy integrating!