Overview
Every end-user that trades or redeems through your platform is registered in GRAIL as a user under your partner. GRAIL stores:- Your internal identifier for the user (
partner_user_id) - The user’s Solana wallet address (unique across all GRAIL users)
- A KYC record — a mix of required structured fields and free-form JSON
kyc_level: "full" can quote trades or redemptions. Partial or basic KYC is rejected at user creation.
GRAIL does not run KYC for you. You KYC users on your side, then push the verified record to GRAIL via the create endpoint. GRAIL stores the record and uses it to gate trading.
The KYC model
Core fields (structured columns, all required):| Field | Type | Notes |
|---|---|---|
country | string | ISO-3166-1 alpha-2 (PK, AE, SA, …). Must be active in GRAIL. |
full_name | string | 1–255 characters. |
kyc_provider | string | Label of your KYC provider (e.g., "sumsub", "manual"). Free-form. |
kyc_level | string | Must be "full". |
kyc_verified_at | ISO-8601 | When you completed KYC on your side. |
kyc_data— any provider-specific fields you want to retain (e.g., document types, ID numbers, risk scores). Stored verbatim.
Advisory ID validation
Ifkyc_data includes both id_type and id_number, GRAIL looks up the country/ID-type pair in its registry and — if a regex is registered — validates id_number against it. For example, for Pakistan:
id_type: "CNIC"→id_numbermust match\d{5}-\d{7}-\d(e.g.,12345-1234567-1)
Step 1 — Look up supported countries
Before registering users, make sure the user’s country is supported. The list is stable; you only need to do this once. If a country you need isn’t supported, contact ORO.There is no public endpoint to list countries in the partner API today. ORO seeds the country list (e.g.,
PK, AE, SA on devnet). If you submit a user with an unsupported country, you’ll get 400 invalid_request: Unsupported or inactive country.Step 2 — Create the user
Uniqueness rules
GRAIL enforces two uniqueness constraints:wallet_addressis unique globally across all GRAIL users (any partner). You cannot register the same Solana wallet twice.user_idis unique within your partner. Two partners may each have a user withuser_id: "user_001", but you cannot have two.
409 user_already_exists.
Step 3 — Look up a user
403 partner_mismatch — each partner can only see its own users.
Trade / redemption prerequisites
The following gate every buy, sell, and redemption call. If a user fails any of them, the quote is rejected before the transaction is built:- User must exist (
404 user_not_foundif not) - User must belong to the authenticated partner (
403 partner_mismatch) - User
statusmust be"active"(403 user_suspended) - User
kyc_levelmust be"full"(400 kyc_level_insufficient) - Your partner must have an on-chain config set up (
400 onchain_config_missing) — this is set up by ORO at onboarding - Your partner must have a registered wallet (
400 wallet_missing) — also set up by ORO
