Endpoints
Magic Checkout
Server-side only. These endpoints return a named person's home address from their phone number. An API key in browser code would expose your entire customer address book to anyone who opens dev tools. Call this from your backend and proxy the result.
Two endpoints for a phone-first checkout: look up what the shopper used last, and save back what they confirmed.
GET /api/v1/checkout/address/{mobile}
POST /api/v1/checkout/addressThe flow
- Shopper types their mobile number.
GETreturns their most recently used address, plus the rest of their book.- They accept it, pick another, or edit it.
POSTsaves the result — updating the matched address or adding a new one.
1. Look up the shopper
curl "https://address.s2coder.com/api/v1/checkout/address/9876543210" \
-H "X-API-Key: YOUR_API_KEY"{
"success": true,
"mobile": "9876543210",
"found": true,
"address": {
"id": 812,
"mobile": "9876543210",
"address": "3/216 Vibhuti Khand",
"locality": "Gomti Nagar",
"city": "Lucknow",
"district": "Lucknow",
"state": "Uttar Pradesh",
"pincode": "226010",
"latitude": 26.8535,
"longitude": 81.0065,
"formatted": "3/216 Vibhuti Khand, Gomti Nagar, Lucknow, Uttar Pradesh, 226010",
"updated_at": "2026-08-12T09:14:22+00:00"
},
"addresses": [ ... ],
"count": 2
}
address is what to prefill the form with. addresses is
the full book, newest first, for a "deliver to" picker.
A first-time shopper returns 200 with
"found": false and "address": null — not a
404. Render an empty form; it is not an error.
2. Save what they confirmed
curl -X POST "https://address.s2coder.com/api/v1/checkout/address" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"mobile": "9876543210",
"address": "3/216 Vibhuti Khand",
"locality": "Gomti Nagar",
"city": "Lucknow",
"state": "UP",
"pincode": "226010"
}'{
"success": true,
"created": false,
"updated": true,
"address": { "id": 812, ... }
}201 when a new address was added, 200 when an existing one was updated.
Required fields
| Field | Required | Notes |
|---|---|---|
| mobile | Yes | Any common format; normalised to ten digits. |
| pincode | Yes | Six digits starting 1-8. |
| state | Yes | Abbreviations expand — UP becomes Uttar Pradesh. |
| address / street / house / locality | One of | A PIN code alone is not a deliverable address. |
| address_id | No | Send it when the shopper picked a saved address, so that exact row is updated. |
| landmark, district, latitude, longitude, place_id, country | No | Stored when supplied. |
How update-vs-add is decided
This is the part worth understanding, because it decides whether a shopper loses an address.
-
If
address_idis supplied and belongs to the same mobile, that record is updated. The mobile check is deliberate: an id alone must not be enough to write into another customer's record. - Otherwise the submitted address is fingerprinted and matched within that customer's book. Same place, written any way, updates the existing row.
- No match means a genuinely different address, so it is added. A shopper ordering to their office does not lose their home address.
A successful save also bumps the address to the top of the customer's list, so "most recently used" is what you get back next time — including when they simply re-confirmed an address without editing it.
Isolation
Checkout reads and writes only the calling account's own customers. Another
merchant's key returns "found": false for the same phone number, and
the shared reference dataset is never exposed here.
Server-side example
use Illuminate\Support\Facades\Http;
$api = Http::baseUrl('https://address.s2coder.com/api/v1')
->withHeaders(['X-API-Key' => config('services.s2address.key')])
->timeout(5);
// 1. Shopper enters their phone number.
$book = $api->get("checkout/address/{$mobile}")->json();
if ($book['found']) {
// Prefill with $book['address']; offer $book['addresses'] as a picker.
}
// 2. They confirm or edit, then you place the order.
$saved = $api->post('checkout/address', [
'mobile' => $mobile,
'address' => $request->input('address'),
'locality' => $request->input('locality'),
'city' => $request->input('city'),
'state' => $request->input('state'),
'pincode' => $request->input('pincode'),
// Present only if they picked a saved address rather than typing one.
'address_id' => $request->input('address_id'),
])->json();
$shipTo = $saved['address'];