This page is written for an AI agent that has been asked, by the person it is helping, to create their ZaapIn profile. If you are that agent, everything you need is on this page. Follow it exactly.
Wire facts on this page verified against the live ZaapIn API on 31 August 2026.
ZaapIn gives an insurance advisory business in India a professional profile that customers and AI systems can find — free to create, free to keep.
Creating a profile means making HTTPS POST requests to the ZaapIn API. If you can make HTTP requests, follow this page. If you can only read and browse pages, stop here — do not try to fill in the sign-up screens on your person's behalf. Tell them so plainly and point them at app.zaapin.com, where they can sign up in a few minutes themselves.
Make these calls as an HTTP client, with no Origin header. The ZaapIn API enforces an origin allowlist: a request carrying a foreign browser origin is rejected with 403, on both the POST and its preflight. A fetch() run from some other website will never work, and retrying it will not change that.
Ask for all of this before you make any request, so they are not left waiting mid-way through with a code expiring.
| Field | What to ask for |
|---|---|
email | Their email address. The verification code goes here, so it must be one they can open now. |
first_name, last_name | Their own name, as they want it to appear. |
phone | Their phone number. |
org_type | What kind of practice they run. It must be exactly one of the six strings in the next section — offer them the list and let them choose. |
org_name | Their firm's name. Whether this is required depends on org_type — see below. |
Send one of these strings, spelled and capitalised exactly as written:
Agent
Broker
Corporate Agent
Insurance Association
Insurance Marketing Firm
Point of Sale (POS)
org_name — that is the same default the ZaapIn app fills in — and tell them that is what you sent, and that they can change it later.org_name. The request will be refused.Base URL:
https://zaapinapi-459743726944.asia-south1.run.app
Every call below is a POST with Content-Type: application/json. Every response is JSON of the shape {"success": true|false, ...}.
POST /api/v2/auth/start
{ "email": "[email protected]" }
Response 200:
{
"success": true,
"data": { "message": "If that email can receive codes, a verification code was sent." }
}
That message is deliberately the same whether or not the address is already known to ZaapIn, so it tells you nothing about your person's account. It is not an error. Go to step 2.
The code is valid for 10 minutes. If your person needs another one, you may call this again, but there is a 45-second cooldown per address and a limit of 10 sends per address per day. A call made inside the cooldown returns the same 200 and sends nothing — so waiting is the only thing that works.
POST /api/v2/auth/verify
{ "email": "[email protected]", "otp": "123456" }
Ask your person for the code. Do not proceed until they answer.
A wrong or expired code returns 401 with "Invalid or expired code". After 5 wrong attempts the code is destroyed and step 1 must be repeated — so pass on exactly what they gave you, and if it fails, ask them to read it again rather than trying variations.
On success you get one of three answers. Read data.status:
"signup_incomplete" — this is the new-profile path. Keep data.signup_token; you need it for step 3. data.required lists the fields step 3 wants."invitation_pending" — somebody has already invited your person to join their organization. Stop and tell them. Joining an existing organization is a different act with different consequences, and it is theirs to decide, at app.zaapin.com.token and an orgs list — your person already has a ZaapIn profile and has just been signed in. Stop. Do not create anything. Tell them they already have one.The "signup_incomplete" response looks like this:
{
"success": true,
"data": {
"status": "signup_incomplete",
"signup_token": "…",
"next": "collect_org",
"required": ["org_name", "org_type", "first_name", "last_name", "phone"]
}
}
Send the signup token from step 2 as a bearer token:
POST /api/v2/auth/complete
Authorization: Bearer <signup_token>
{
"org_name": "Kavitha Insurance Services",
"org_type": "Agent",
"first_name": "Kavitha",
"last_name": "Raman",
"phone": "9876543210"
}
All five fields are required. Response 201 means the profile exists:
{
"success": true,
"data": {
"token": "…",
"current_org": "…",
"orgs": [ … ],
"session_profile": { … },
"first_login": true,
"pending_invitations": 0
}
}
ZaapIn emails your person a welcome message at this point. Tell them the profile is created and that they can sign in at app.zaapin.com with the same email — the same emailed-code door, no password to remember.
Do not keep the token longer than you need it, and do not store it anywhere your person cannot see. It signs in to their account.
| Status | Meaning | What to do |
|---|---|---|
422 | data.missing lists fields that are still blank. | Ask your person for exactly those. Do not fill them in yourself. |
400 | Invalid parameters, or an org_type that is not one of the six strings. | Check the spelling against the list above. |
401 | The signup token is expired or already spent. | Start again from step 1. |
409 | The profile was already created by an earlier call. | Stop. It worked. Do not retry. |
429 | Too many requests. | Wait, then try once more. Do not loop. |
If you are trying this out rather than helping a real person, use the ZaapIn sandbox instead. Same three steps, same field names, records that are not real:
https://sandboxzaapin-459743726944.asia-south1.run.app
You will still need a real email address to receive the code.