Skip to main content
A global (user-level) API key can create a business entity and run its KYB onboarding without touching the dashboard: business details, the representatives (beneficial owners and officers), each representative’s identity verification, supporting documents, and the final submission. Every response includes a next_step object that tells you what’s outstanding, so you don’t infer it from status.
This is self-serve onboarding for entities your key owns. The key’s user is the creator and admin, not a representative of the entity. To onboard entities on behalf of your customers as a platform, use Partner Onboarding instead.

You’ll need

  • A global API key (user-scoped, not entity-scoped) with the entity:create scope for writes and accounts:read to read and list onboarding state. Onboarding routes reject entity-scoped keys with 403.
  • No x-entity-id header. The entity is addressed in the URL path.
Testing in sandbox. The examples below use the production base URL https://api.meow.com/v1. To run the whole flow end to end without touching a human review queue, point every call at https://api.sandbox.meow.com/v1 instead — the paths are identical. Sandbox (and dev) also expose the approval simulation that stands in for compliance review, so you can drive an application all the way to approved and open a live checking account. Non-production keys are granted the simulations:write scope automatically.
Every onboarding read returns a next_step. For a US entity mid-onboarding it looks like this (address is a US-only requirement — see documents):
FieldMeaning
stepThe step the application is on now.
phasebusiness_infoready_to_submitsubmitted.
missingThe items still required to clear the current step.
required_proof_typesKYB documents still owed, as proof_type values. Pass each one when requesting an upload URL.
can_submittrue once everything required has been collected.
The loop: call an endpoint, then GET /entities/{entity_id}, act on next_step.step, repeat until can_submit is true, then submit.
stepDo this
collect_business_details, collect_business_addressesCreate the entity, or update its details.
collect_additional_detailsUpdate business details with the account purpose and digital-currency answers.
manage_representativesAdd representatives, marking one is_primary.
complete_identity_verificationVerify each representative.
upload_documentsUpload the documents named in required_proof_types.
complete_due_diligenceComplete the required due-diligence forms. Submittable forms go through the API; others must be finished in the dashboard.
submit_applicationSubmit the application.
Some entities draw an extra due-diligence step (complete_due_diligence) before they can submit. Forms that collect plain data are submittable through the due-diligence endpoints; forms that require document uploads must be finished in the Meow dashboard. A follow-up information request after submission (resolve_info_requests) is dashboard-only; the API surfaces it in next_step so you know when to direct the business there.

1. Create the entity

POST /entities creates the entity and returns its public ID. The creating user is granted admin, so the same key can act on the entity immediately. Send an empty body to create a bare entity, or seed any KYB business details up front.
Response
Save id. It’s the {entity_id} for every call below, and the x-entity-id header once the entity is onboarded and you call entity-scoped APIs. legal_structure is one of: ccorp, corp, scorp, llc, llp, lp, partnership, soleprop, nonprofit, trust, estate, foreign_entity, scheme.
Pass your own reference_id to make creation idempotent. Retrying a create with a reference_id you’ve already used returns the original entity instead of creating a duplicate, so a network timeout never leaves you with two entities.

2. Update business details

PATCH /entities/{entity_id}/business-details fills in or corrects KYB details before the application is submitted. Send only the fields you want to change; anything you omit keeps its current value. Use it for the business profile the create call didn’t include, and to answer the account-purpose and digital-currency questions (collect_additional_details).
The response is the refreshed onboarding status, including the updated next_step. Send physical_address together with business_address; omitting it keeps any physical address already on file, or uses the legal address when none is set.

3. Add representatives

POST /entities/{entity_id}/representatives records a beneficial owner or officer and returns its representative_id. This step is create-only. Verify the representative separately (section 4). Mark exactly one representative as the signer with is_primary: true; setting it demotes any previous primary. A primary representative is required before the application can be submitted. To promote a representative already on file, call POST /entities/{entity_id}/representatives/{representative_id}/make-primary — it makes that representative the signer and demotes the current one. Allowed until the application is submitted.
Response
  • title_id is one of: chief executive officer, chief financial officer, chief operating officer, president, general partner, managing member, finance manager.
  • percent_ownership is required when is_beneficial_owner is true, between 25 and 100. Total beneficial ownership across representatives cannot exceed 100.
  • Each email is unique per entity. Re-posting the same address returns 400.

4. Verify each representative

KYC is per representative, with two ways to do it. Pick one per person.
Submit the representative’s identity data and Meow runs verification on it.
Response
For id_type: us_ssn send nine digits with or without dashes (123-45-6789 or 123456789); for us_ssn_last_4 send the last four.ip is required: the end user’s IPv4 or IPv6 address, forwarded to the verification provider as a fraud signal.
Sandbox testing. In sandbox and dev the verification provider only clears a known test identity, so use Leslie Knope below. The reliable path is the self-verify link (the “They self-verify” tab): mint the link and complete the flow with these exact details. A representative’s kyc_status must reach approved before the application can be approved — poll the representatives array to confirm.
Verification completes asynchronously. next_step advances once every representative has started verification, not once they pass, so track the actual outcome per representative via their kyc_status in the representatives array on the onboarding status, or the identity_verification.* webhooks. A representative’s kyc_status matches the webhook stream; action_required means that person needs another step (for example, a document) — mint a verification link and share it so they can finish. The top-level kyc_status reflects the primary representative.

5. Upload supporting documents

next_step.required_proof_types lists exactly which documents the entity still owes. For a US entity that’s typically ["incorporation", "address"]. Each one uses a three-step flow: get a pre-signed URL, PUT the bytes, then confirm. Repeat the flow for each proof type — for example, the incorporation certificate first, then the proof of physical address:
1

Request an upload URL

Response
2

PUT the file to upload_url

Use the same Content-Type you requested, keep the file under max_bytes, and upload before the URL expires.
3

Confirm the upload

Response
4

Repeat for the proof of physical address

Pass each value from required_proof_types as the proof_type. For US entities, required_proof_types includes both incorporation and address as standard requirements. address is proof of physical address at the entity level — a utility bill, bank statement, or lease/rental agreement evidencing the entity’s relationship to its physical address. The address requirement applies to US entities only; foreign entities are not asked for it. Other common values include articles_of_organization, bylaws, operating_agreement, ein, bank_statement, and beneficial_owner_id.
Address documents uploaded for a representative do not satisfy the entity-level address requirement — the document must evidence the entity’s physical address. next_step.can_submit stays false until every proof type in required_proof_types has been uploaded.

Complete required due diligence

Some industries draw an extra enhanced due diligence (EDD) step before the application can be submitted. When one applies, next_step.step is complete_due_diligence. List the required forms, then for each form that’s submittable through the API, fetch its schema and submit it. Forms that collect document uploads can’t be submitted through the API (requires_webapp: true) and must be completed in the Meow dashboard.
1

List the required forms

GET /entities/{entity_id}/due-diligence returns each required form with its completion status and whether it must be finished in the web app.
Response
2

Fetch a submittable form's schema

GET /entities/{entity_id}/due-diligence/schema/{form_type} returns the form’s pages and fields — types, choices, validation, and conditional visibility — so you can build a valid submission. Only forms submittable through the API have a schema.
3

Submit the completed form

POST /entities/{entity_id}/due-diligence submits one form. Set form_type to the form you’re answering; form_data matches that form’s schema. The response is the refreshed onboarding status.
Repeat for each submittable form. Once every required form is complete — and any requires_webapp forms are finished in the dashboard — next_step advances past complete_due_diligence and can_submit can turn true.

6. Submit the application

Once next_step.can_submit is true, submit the application with POST /entities/{entity_id}/submit. Choose the checking account product to open, and attest that you are authorized to submit on the business’s behalf. If anything is still outstanding, this returns 400 with the remaining requirements; check next_step.can_submit first.
Response
  • banking_account_product_type is grasshopper or crb.
  • attestation must be true.
Once submitted, the application moves to review and can no longer be edited. Meow moves status to under_review, then approved or rejected. Watch for the outcome with webhooks (below) or by polling the status endpoint.

Sandbox: simulate application approval

In sandbox and development environments there is no human compliance review, so a submitted application would otherwise sit in under_review forever. Simulate the approval with POST /simulations/entities/{entity_id}/application_approval. It approves the application as if compliance review had passed and kicks off checking-account onboarding.
  • Every representative’s kyc_status must be approved first. Real review never approves an application whose beneficial owner failed KYC, and neither does the simulation — it returns 400 and names how many representatives still need to pass. Poll GET /entities/{entity_id} and confirm every entry in the representatives array shows kyc_status: "approved" before calling this. In sandbox, get there with the verification link and the test identity.
  • The application must already be submitted (section 6).
  • The body is optional. banking_account_product_type defaults to grasshopper; crb is also supported.
  • Use a global (user) API key with the simulations:write scope (granted automatically on non-production keys); the key’s user must be an admin of the entity.
After calling it, the application’s status moves to submitted immediately and to approved once the checking account activates. Poll GET /entities/{entity_id} or subscribe to the application.* webhook events to observe the transition. The call is safe to repeat. If account opening stalls in the sandbox (the status sits at submitted for more than a few minutes), call it again — a retry completes the stalled opening and adopts the account the sandbox bank already created, without opening a duplicate.
Simulation endpoints are only available in sandbox and development environments. In production they return 404 Not Found.

7. Track progress to submission

GET /entities/{entity_id} returns the lifecycle status, uploaded documents, next_step, and a representatives array with each representative’s kyc_status. The top-level kyc_status reflects the primary representative.
Response
statusMeaning
pending_document_uploadNo documents uploaded yet.
pending_user_actionStill collecting required data.
submittedSubmitted; queued for review.
under_reviewMeow is reviewing the application.
approvedKYB approved (and an account is open).
rejectedKYB rejected.

8. List your entities

GET /entities returns every entity your key’s user owns, each tagged with its onboarding_type, with opaque-offset pagination.
Response
When page is non-null, pass page.nextOffset as the offset query parameter for the next page. When page is null, you’ve reached the end.

Track updates with webhooks

Instead of polling GET /entities/{entity_id}, subscribe once and let Meow push each change. A global key’s own onboarding events — identity_verification.* for KYC outcomes and application.* for KYB lifecycle changes — deliver to a regular webhook subscription, so the same key you onboard with can receive them.
Save the signing_secret from the response — it is returned once. Omit event_types (or send null) to receive every event the key can see. Each delivery carries the same status values you would otherwise poll for, so you can drive the whole flow off the stream. The key needs the webhooks:write and webhooks:read scopes, and the url must be public HTTPS. See the webhooks guide for signature verification, retries, and out-of-order handling.

End to end

See also

Create an entity

Full request contract for POST /entities.

Update business details

Fill in or correct KYB details before submission.

Add a representative

Beneficial owners and officers, with the primary signer flag.

Submit the application

Choose the account product and attest, then send for review.