Onboarding a business means completing KYB. Unlike an individual application, which is a single object you fill in and submit, a business application is a tree: the business itself, one or more related parties, and a set of document requests that Jiko derives from what you tell it. You submit once, when the whole tree is complete.
When the application reaches APPROVED, Jiko creates a customer, and the application's customer_id is populated. That customer can then hold pockets.
Feature flags are set by Jiko per partner and evaluated against the API user making the request. A call that needs a flag you do not have fails with 403. Ask your Jiko point of contact for the ones you need.
| Flag | Needed for | Without it |
|---|---|---|
non_us_id_citizenships | Submitting INTERNATIONAL_ID identification on a related party. A comma-separated list of ISO 3166-1 alpha-2 citizenship codes; a non-empty list enables the feature, empty or absent disables it | 403 where your partnership has no allowlist at all, and 422 where it has one but the related party's citizenship is not on it |
Nothing else about business onboarding is flag-gated. POST /api/v1/business-applications/ and the rest of the tree are available to every partner.
- The Partner Obligations discharged before you start. Verify ownership of the phone number and the email address on the application, and display Jiko's agreements — fetched from
GET /api/v1/agreements/— recording theversionshown and the timestamp of consent. Re-fetch for every new application; the current version changes, and consent against a stale version is not consent to what Jiko is obliged to have shown. None of this is checked by the API. - API credentials for the environment you are calling. Build against sandbox first: a business application is a tree assembled over several calls, and the document list moves as you fill it in. The sandbox status simulator makes every terminal state reachable in seconds.
- A way to upload PNGs. Document uploads require a
Content-Typeofimage/png; anything else is rejected at the header. Convert before you upload. - Exactly one related party carrying
CONTROL_PERSON. None isCONTROL_PRONG_MISSINGat submission; more than one isMULTIPLE_CONTROL_PRONGS. Both block submission outright. - Ownership percentages that add up. Each related party's
ownership_percentageis a string parseable to a number between 0 and 1 —"0.51"is 51% — and the percentages across active beneficial owners cannot total more than 100%. agreement_consentgiven by a control person or authorized representative. The API does not check this —agreement_consentcarries only a version and a timestamp, with no signer field — so enforce it in your own UI and record on your side who accepted.- A complete
risk_infoblock before you read the document list. Document requests are derived from the entity type, the industry, the risk categories and the related parties. Read the list thin and it changes under you. - Every derived document request uploaded and not
INVALID. AnINVALIDdocument does not fail the application, but the application will not move until it is replaced. - A path for answering RFIs. There is no webhook for an RFI. An application sitting in
MANUAL_REVIEWwith an open RFI is waiting on you, and it waits silently. - A webhook subscription for
application.approved,application.manual_review,application.documents_neededandapplication.rejected. The payload isapplication_idonly, so each event means "fetch the application" — including the approval, which is the only placecustomer_idappears. Subscriptions are recorded against the API user that creates them.
- Create the business application.
POST /api/v1/business-applications/ - Add related parties. Every control person and authorized representative gets their own application.
- Read the document requests. Jiko derives them from the entity type and the risk answers — you cannot know them up front.
- Upload each document.
- Submit.
POST /api/v1/business-applications/{application_id}/apply/ - Respond to RFIs, if Jiko's review raises any.
- Wait for a terminal status, delivered by webhook.
Steps 1–4 are incremental. The application starts in CREATED and every field is optional on the create call, so you can build it up over repeated PATCH /api/v1/business-applications/{application_id}/ calls as your own UI collects the data. Validation of completeness happens at submission, not at creation. Related parties can be updated and deleted the same way, right up until you submit.
Step 4 is a loop. Supplying the last outstanding document does not resume the review: the application moves from DOCUMENTS_NEEDED to PENDING, which means "nothing is outstanding, and Jiko is waiting for you to resubmit". You call apply again. An application parked in PENDING is waiting on you, and no webhook will say so.
| Step | Purpose | Endpoint |
|---|---|---|
| 1 | Fetch the agreements to display | GET /api/v1/agreements/ |
| 2 | Create the business application | POST /api/v1/business-applications/ |
| 3 | Add fields incrementally as your UI collects them | PATCH /api/v1/business-applications/{application_id}/ |
| 4 | Add a related party | POST /api/v1/business-applications/{application_id}/related-party-applications/ |
| 5 | Correct or remove a related party before submission | PATCH / DELETE /api/v1/business-applications/{application_id}/related-party-applications/{related_party_application_id}/ |
| 6 | Read the derived document checklist | GET /api/v1/business-applications/{application_id}/documents/ |
| 7 | Upload a document (Content-Type: image/png) | POST /api/v1/documents/{document_id}/ |
| 8 | Submit, and resubmit after a DOCUMENTS_NEEDED round | POST /api/v1/business-applications/{application_id}/apply/ |
| 9 | Read the status and, on approval, customer_id | GET /api/v1/business-applications/{application_id}/ |
POST /api/v1/business-applications/| Field | Notes |
|---|---|
id | Optional client-supplied UUID |
name | Legal name |
entity_type | SOLE_PROPRIETOR, CORPORATE, LLC, PARTNERSHIP, INCORPORATED_ASSOCIATION, UNINCORPORATED_ASSOCIATION, NON_BANK_FINANCIAL_INSTITUTION, NON_PROFIT, TRUST and others |
doing_business_as | DBA name, where it differs from the legal name |
identification_number | EIN or equivalent |
address | ISO-format address |
website | |
contact | Business contact — name, email, phone |
formation_date | |
industry | An industry code, plus other_industry free text when the code is "other" |
risk_info | See below |
agreement_consent | Consent to Jiko's agreements. See Who may consent to the agreements |
This block is what determines which documents Jiko asks for and whether the application routes to manual review. Fill it in properly and the document list settles early; leave it thin and the list changes under you.
These are always required: business_activity_location, account_usage, monthly_transactions, first_month_deposit, source_of_funds, annual_revenue and company_mission.
These become required depending on what else you sent:
| When | Also required |
|---|---|
risk_categories contains CRYPTOCURRENCY | has_current_enforcement_actions |
risk_categories contains FINANCIAL_OR_MONEY_MOVEMENT | has_current_enforcement_actions and primary_regulator |
source_of_funds is CLIENT_OR_EXTERNAL_FUNDS | source_of_funds_explanation |
primary_regulator is a free-text string in the API, but the answers Jiko expects are a short set: FRB, OCC, FDIC, FINRA, CFTC, FinCEN (MSB registration), State regulatory agency, Other. Offer those rather than an open box.
| Field | Values |
|---|---|
risk_categories | INTERNET_GAMBLING, CANNABIS, CRYPTOCURRENCY, CROWDFUNDING, FINANCIAL_OR_MONEY_MOVEMENT, NON_US_ENTITY, FINTECH_OR_BAAS |
company_mission | Free text |
has_current_enforcement_actions | Boolean |
primary_regulator | Free text; see the accepted answers above |
business_activity_location | PRIMARILY_US, MIX_OF_US_AND_NON_US, PRIMARILY_NON_US |
source_of_funds | INTERNAL_FUNDS, CLIENT_OR_EXTERNAL_FUNDS, CRYPTOCURRENCY_EXCESS_RESERVES and others, with source_of_funds_explanation |
account_usage | MONEY_STORAGE, MONEY_STORAGE_US_BANKS, MONEY_STORAGE_NON_US_BANKS, CRYPTOCURRENCY_EXCESS_RESERVES and others |
annual_revenue | Banded, for example PRE_REVENUE |
monthly_transactions | Banded |
first_month_deposit | Banded |
is_finra_registered_broker_dealer | Boolean |
Declaring CRYPTOCURRENCY as a risk category, for instance, pulls in a distinct set of document requests — legal analysis of the business model, coins and tokens listed, coin rating policy, blockchain analytics used, market manipulation policy, BSA/AML/OFAC policies, independent AML audit report, internal risk assessment. Those requests do not appear until the category is declared.
POST /api/v1/business-applications/{application_id}/related-party-applications/
GET /api/v1/business-applications/{application_id}/related-party-applications/
GET /api/v1/business-applications/{application_id}/related-party-applications/{related_party_application_id}/| Field | Notes |
|---|---|
name | |
address | ISO-format address |
date_of_birth | |
identification_number | SSN, passport, TIN, driver's license or international ID. Returned masked |
phone_number | E.164 |
email | |
title | Their role in the business, free text |
roles | CONTROL_PERSON and/or AUTHORIZED_REPRESENTATIVE — the only two values the API accepts |
ownership_percentage | A string parseable to a number between 0 and 1. "0.51" is 51% |
citizenship | ISO 3166 country code |
address.state is required only when address.country is US.
There are only two roles, so a beneficial owner or a member of senior management who is neither the control person nor an authorized representative is still registered as a related party — recorded through title and ownership_percentage rather than through a role of their own.
identification_number comes back masked on every read — *****6789. There is no way to read the real value back.
The consequence: do not echo it into a PATCH. An update that sends the object you just fetched will write the mask over the real number, and the application then carries *****6789 as the related party's identification. Send only the fields you are actually changing.
Exactly one related party must carry CONTROL_PERSON. Submitting with none, or with more than one, is rejected — the submission exception reasons are explicit about this: CONTROL_PRONG_MISSING and MULTIPLE_CONTROL_PRONGS.
The agreement_consent on the business application may only be given by a related party holding the CONTROL_PERSON or AUTHORIZED_REPRESENTATIVE role.
The API does not check this. agreement_consent carries only a version and a timestamp — there is no signer field, and submission does not compare the consent against the related parties. Enforce it in your own UI: present the agreements only to a party carrying one of those roles, and record on your side who accepted them.
INTERNATIONAL_ID is accepted as an identification type for a related party only where the party's citizenship is on your partnership's allowlist. Outside that allowlist, an international ID is rejected at validation. If you onboard non-US control persons, confirm the allowlist with your Jiko point of contact before building the form.
GET /api/v1/business-applications/{application_id}/documents/Document requests are derived, not chosen. They depend on the entity type, the industry, the risk categories and the related parties you have entered, so the list is only meaningful once the rest of the application is filled in. Read it, do not hard-code it.
The set spans entity-formation documents (ARTICLES_OF_INCORPORATION, OPERATING_AGREEMENT, PARTNERSHIP_AGREEMENT, BYLAWS, ARTICLES_OF_ORGANIZATION, CORPORATE_CHARTER, TRUST_FORMATION_RECORDS, LIST_OF_TRUSTEES, TRUST_VERIFICATION_DOCUMENT, PROOF_OF_501_STATUS, CERTIFICATE_OF_GOOD_STANDING), identity documents for related parties (ID_FRONT, ID_BACK, PASSPORT, SELFIE, ADDRESS_VERIFICATION, IDENTIFICATION_NUMBER_VERIFICATION), financial documents (BANK_STATEMENTS_1–3, FLOW_OF_FUNDS, EIN_CONFIRMATION, ORG_CHART, BUSINESS_DESCRIPTION) and the risk-driven policy documents above.
Upload against the document's own ID:
POST /api/v1/documents/{document_id}/Uploads must carry Content-Type: image/png. The header is pattern-matched, so a JPEG or a PDF is rejected before the file is read — worth knowing early, because most of what a business will hand you is a PDF.
Each document carries a status: PENDING_UPLOAD → PENDING_REVIEW → APPROVED or INVALID. An INVALID document needs to be re-uploaded; it does not fail the application on its own, and it carries an exception_reason saying what was wrong with it. Surface that to whoever is uploading.
You do not have to wait for review to finish before submitting. The bar is that every request is APPROVED or PENDING_REVIEW — that is, nothing is still PENDING_UPLOAD or INVALID.
One set of requests is an either/or. Where INTERNAL_KYC_AUDIT, EXTERNAL_KYC_AUDIT and KYC_POLICIES_AND_PROCEDURES are all requested, the business satisfies them with either EXTERNAL_KYC_AUDIT on its own, or INTERNAL_KYC_AUDIT together with KYC_POLICIES_AND_PROCEDURES. A UI that insists on all three will block a business that has done nothing wrong.
POST /api/v1/business-applications/{application_id}/apply/Submit only when the business application, every related party application and every document request are complete. If anything is missing, the response tells you exactly what, via exception_reasons:
NAME_MISSING, DATE_OF_BIRTH_MISSING, ADDRESS_MISSING, PHONE_NUMBER_MISSING, EMAIL_MISSING, AGREEMENT_CONSENT_MISSING, ENTITY_TYPE_MISSING, FORMATION_DATE_MISSING, INDUSTRY_MISSING, OTHER_INDUSTRY_MISSING, BUSINESS_CONTACT_MISSING, RISK_PROFILE_MISSING, RISK_CATEGORY_MISSING, COMPANY_MISSION_MISSING, ACCOUNT_USAGE_MISSING, PRIMARY_REGULATOR_MISSING, SOURCE_OF_FUNDS_MISSING, RELATED_PARTIES_INCOMPLETE, CONTROL_PRONG_MISSING, MULTIPLE_CONTROL_PRONGS, CITIZENSHIP_MISSING, ROLES_MISSING.
Surface these to whoever is filling in your form. They map one-to-one onto fields.
| Status | Meaning | Who it is waiting on |
|---|---|---|
CREATED | Being filled in. Not yet submitted | You |
SUBMITTED | Submitted, under evaluation | Jiko |
DOCUMENTS_NEEDED | Jiko needs more documents. Read the checklist and upload | You |
PENDING | Every outstanding document has been supplied. Call apply again | You |
MANUAL_REVIEW | Under human review at Jiko | Jiko |
APPROVED | KYB passed. A customer now exists; read customer_id. Terminal | — |
REJECTED | KYB failed. Terminal | — |
CLOSED | Closed for inactivity. Terminal | — |
PENDING is the one to read carefully. It does not mean "in processing" — it is where an application lands once you have cleared the document requests, and it moves no further until you resubmit. CLOSED is worth designing for too: an application that nobody finishes does not sit in CREATED forever.
In sandbox the business's identification_number — the EIN — decides the outcome, so every status is reachable without real KYB. The first digit controls what happens on the first apply:
| Prefix | Status after apply |
|---|---|
2 | DOCUMENTS_NEEDED |
4 | APPROVED |
5 | REJECTED |
| Anything else | MANUAL_REVIEW |
A 2 behaves differently on the way back than the individual path does. Once you have uploaded the requested documents and applied again, a business application goes to MANUAL_REVIEW — not to APPROVED. To reach an approved business customer in sandbox, start from a 4.
Sandbox appends a unique suffix to the identification number you submit, so the same EIN can be reused across applications without colliding. The number you read back is therefore not the one you sent.
Where review needs something a document request cannot express, Jiko opens an RFI — a message thread on the application.
GET /api/v1/business-applications/{application_id}/rfis/
GET /api/v1/business-applications/{application_id}/rfis/{rfi_id}/
POST /api/v1/business-applications/{application_id}/rfis/{rfi_id}/messages/
POST /api/v1/business-applications/{application_id}/rfi-messages/{message_id}/documents/
GET /api/v1/business-applications/{application_id}/rfi-messages/{message_id}/documents/{document_id}/An RFI moves through CREATED → REQUESTED → ANSWERED → APPROVED or REJECTED, and can be CANCELED. Messages are typed OPS (from Jiko) or CUSTOMER (from you), and a message can carry documents.
An application sitting in MANUAL_REVIEW with an open RFI is waiting on you, not on Jiko. Poll the RFI list, or surface the thread into your own support tooling, or the application stalls silently.
| Event | Meaning |
|---|---|
application.approved | KYB passed; a customer exists |
application.manual_review | Routed to human review |
application.documents_needed | More documents required |
application.rejected | KYB failed |
Payload: application_id. Fetch the application to learn what changed and, on approval, to read customer_id.
There is no event for an RFI. RFIs must be polled.
The application's customer_id is the handle for everything downstream:
GET /api/v1/customers/{customer_id}/
POST /api/v2/customers/{customer_id}/pockets/
GET /api/v2/customers/{customer_id}/pockets/For most partnerships, approval creates the customer and nothing else. Opening a pocket is a call you make.
Automatic pocket-and-portal creation at approval does exist, but it is a legacy behavior limited to an explicit allowlist of partner IDs held in Jiko's configuration. If your partnership is on that list, an approved customer already has a pocket and a virtual bank account portal with a routing and account number. If it is not, GET /api/v2/customers/{customer_id}/pockets/ comes back empty and stays empty until you create one. Ask your Jiko point of contact which case applies, and read the pocket list rather than assuming either answer.
A customer may hold up to 20 pockets per partner by default. The limit counts every pocket ever created for that customer, including closed ones — closing a pocket does not free a slot. Create pockets for durable purposes; do not use them as per-transaction or per-invoice containers. Portals, which are uncapped on the bank rails, are the right tool for that.
| Operation | Endpoint |
|---|---|
| List agreements to display | GET /api/v1/agreements/ |
| Create a business application | POST /api/v1/business-applications/ |
| Get a business application | GET /api/v1/business-applications/{application_id}/ |
| Update a business application | PATCH /api/v1/business-applications/{application_id}/ |
| Create a related party application | POST /api/v1/business-applications/{application_id}/related-party-applications/ |
| List related party applications | GET /api/v1/business-applications/{application_id}/related-party-applications/ |
| Get a related party application | GET /api/v1/business-applications/{application_id}/related-party-applications/{related_party_application_id}/ |
| Update a related party application | PATCH /api/v1/business-applications/{application_id}/related-party-applications/{related_party_application_id}/ |
| Delete a related party application | DELETE /api/v1/business-applications/{application_id}/related-party-applications/{related_party_application_id}/ |
| List document requests | GET /api/v1/business-applications/{application_id}/documents/ |
| Upload a document | POST /api/v1/documents/{document_id}/ |
| Submit | POST /api/v1/business-applications/{application_id}/apply/ |
| List / get RFIs | GET /api/v1/business-applications/{application_id}/rfis/ |
| Reply to an RFI | POST /api/v1/business-applications/{application_id}/rfis/{rfi_id}/messages/ |
- Onboarding individuals
- Partner Obligations — phone, email, disclosures, identity proofing
- Businesses reference
- Pockets
- Webhooks