Endpoint
201:
auth_link is a confirmation URL you can redirect the investor to for
approving an ENACH mandate — the same link the exchange already emails/SMSes
them. It’s fetched best-effort at creation time and is absent (field omitted)
for a PHYSICAL mandate, or if it isn’t ready yet. GET /api/mandates/v1/:id
retries fetching it while it’s missing, so poll that endpoint if you need it
and it wasn’t in the create response.
Fields
Validation
Rejected synchronously with400 VALIDATION_FAILED:
start_dateunparseable or in the past.end_dateunparseable or not afterstart_date.typenotENACHorPHYSICAL.amountnot greater than 0.- Neither
bank_account_idnor the full inline trio (account_no+ifsc+account_type) supplied. investor_iddoesn’t exist.
Status lifecycle
Observed status values:
PENDING, REGISTERED, REJECTED, CANCELLED.
GET /api/mandates/v1/:id refreshes the status live from the exchange before
returning it, so polling this endpoint reflects the latest registration state.
Or listen for webhook events
mandate.registered, mandate.rejected, mandate.cancelled instead of
polling.
Upload a physical mandate scan
file — the scanned, signed mandate form. Only valid for a
PHYSICAL mandate. On acceptance the mandate becomes REGISTERED; a rejection
returns 422 UCC_REJECTED.
Link a UMRN
Using a mandate for payment
When a payment references a mandate, two checks run at payment time:Read endpoints
Public mandate confirmation link
Instead of registering a mandate directly, you can propose one and have the investor confirm it themselves — the same self-serve pattern as the public onboarding link for investors and the public order link.201: { "success": true, "data": { "link_id": "8f3e2b1a-..." } } —
no mandate is registered yet, only the proposal. Share
https://<your-ui>/mandate-confirm?linkId=8f3e2b1a-... with the investor.
The investor reviews it via GET /api/public/v1/mandate-links/:link_id
(X-Draft-Secret header for the PIN, if set) and confirms via
POST /api/public/v1/mandate-links/:link_id/confirm — the same validated
create path as POST /api/mandates/v1/, returning the same response shape
including auth_link.
Both the pre-confirm and post-confirm GET response also include a
bank_display object — { "account_no": "****1234", "ifsc": "...", "account_type": "..." } — a masked view of the proposal’s bank account,
resolved server-side. The public link never returns a raw bank_account_id
or account number, whether the proposal referenced a saved bank account or
was built from a manually-typed account_no/ifsc.
auth_link (ENACH only) is where the investor should be redirected to
approve the debit with their bank — the same link the exchange already
emails/SMSes them. It’s a best-effort fetch and can lag a beat behind
confirmation, so don’t assume it’s present the instant confirm returns:
poll GET /api/public/v1/mandate-links/:link_id every few seconds until
mandate.auth_link appears (it’s blank for PHYSICAL mandates and stays
blank if the mandate was REJECTED), then redirect. As with order links,
this link expires after 7 days (410 GONE) and a second confirm on the same
link is 409 ALREADY_CONFIRMED — unlike the investor onboarding link, which
never expires.