User-to-user gifting
Let one of your users gift gold or silver to someone else, verified by an OTP sent to the sender's own mobile.
Gifting is a user → user transfer: the assets leave one of your end users' holdings and land with whoever they choose. You orchestrate it, but the value is theirs, which is why every gift is OTP-verified. To move assets out of your own wallet instead, see Sending assets.
Before you start
Gifting needs the gift capability on your profile, and the sender has to clear two checks:
| Requirement | If it is not met |
|---|---|
| Approved KYC | The sending user must have completed and passed KYC, or the quote returns 403 KYC_REQUIRED. |
| Sufficient holdings | The sender must hold enough of the asset to cover the gift plus the 0.25% fee, or the quote returns 400 INSUFFICIENT_BALANCE. |
See KYC for how to get a user verified, and Errors for the full envelope.
1. Quote the gift
The quote prices the gift and triggers the OTP in one call — there is no separate "send OTP" step.
/partner/users/:user_code/gift/quotegift| Field | Type | Description | |
|---|---|---|---|
| receiver_mobile | string | required | Who receives the gift, 10 to 15 digits. Auto-created if they are new to OroPocket. |
| asset_type | string | required | Either "gold" or "silver". |
| amount_inr | number | optional | Rupee value to gift. Provide this OR amount_grams, not both. |
| amount_grams | number | optional | Exact grams to gift. Provide this OR amount_inr. |
| Field | Type | Description |
|---|---|---|
| gift_id | string | Pass this to the resend and confirm calls. Valid for 10 minutes. |
| sender_user_code | string | The user_code the gift is debited from, echoed back. |
| receiver | object | { mobile, name, exists, will_be_created } — will_be_created is true when we will open a new account at confirm. |
| breakdown | object | Costing for the gift — see the table below. |
| otp | object | { required, sent, channel, sent_to, resend_after_seconds } — sent_to is masked, resend_after_seconds is 45. |
Inside breakdown:
| Field | Type | Description |
|---|---|---|
| rate_per_gram | number | Locked rate for this gift. |
| price_basis | string | Which side of the spread priced the gift. |
| receiver_grams | number | Grams the receiver is credited. |
| sender_grams | number | Grams debited from the sender — receiver grams plus the fee. |
| fee_grams | number | Platform fee in grams. |
| fee_inr | number | The same fee in rupees. |
| fee_percentage | number | 0.25 — the fee is 0.25% of the gift. |
| amount_inr | number | Rupee value of the gift. |
1234 and no SMS is sent.curl -X POST https://api.oropocket.com/partner/users/usr_xxx/gift/quote \
-H "Authorization: Bearer oro_live_xxx" \
-H "Content-Type: application/json" \
-d '{"receiver_mobile":"9876543210","asset_type":"gold","amount_inr":500}'2. Resend the OTP (optional)
If the sender never got the code, resend it against the same quote. Wait out resend_after_seconds (45) before calling.
/partner/users/:user_code/gift/otp/resendgift| Field | Type | Description | |
|---|---|---|---|
| gift_id | string | required | The gift_id from the quote. The quote's own 10-minute clock is not extended. |
3. Confirm the gift
/partner/users/:user_code/gift/confirmgift| Field | Type | Description | |
|---|---|---|---|
| gift_id | string | required | The gift_id from the quote, confirmed within its 10-minute window. |
| otp | string | required | The code the sender received on their registered mobile. |
| Idempotency-Key | header | optional | Strongly recommended. Any string up to 100 characters — retrying with the same key replays the original response instead of gifting twice. |
| Field | Type | Description |
|---|---|---|
| transaction_id | string | Identifier for the resulting trade. |
| gift_id | string | The quote this settled, echoed back. |
| status | string | Outcome of the gift. |
| side | string | "gift" — how gifts are distinguished in the trades feed. |
| sender_user_code | string | The user the assets came from. |
| receiver | object | { mobile, is_new_user } — is_new_user is true when the account was created by this gift. |
| asset_type | string | "gold" or "silver". |
| amount_inr | number | Rupee value of the gift. |
| asset_quantity_grams | number | Grams credited to the receiver. |
| fee_inr | number | Fee charged, in rupees. |
| fee_grams | number | The same fee in grams. |
| sender_new_balance_grams | number | The sender's remaining balance for that asset. |
| created_at | string | ISO timestamp of the gift. |
401 INVALID_OTP. After 5 failed attempts the quote locks — request a fresh one with /gift/quote, which also issues a new OTP.curl -X POST https://api.oropocket.com/partner/users/usr_xxx/gift/confirm \
-H "Authorization: Bearer oro_live_xxx" \
-H "Idempotency-Key: 8f14e45f-cea1-4b2c-9d3a-1f2e3d4c5b6a" \
-H "Content-Type: application/json" \
-d '{"gift_id":"gft_xxx","otp":"1234"}'Finding gifts later
Gifts show up in GET /partner/trades alongside buys and sells, tagged with side: "gift". Subscribe to webhooks if you would rather be pushed the event than poll for it.