⚡ Saudi Address API

MyShortAddress API

Turn coordinates or a Saudi Short Address (e.g. RCDA6608) into a full, structured national address — district, street, building number, postal code and more — with one HTTPS call.

Base URL
https://your-host
Protocol
HTTPS · JSON
Auth
X-API-Key header
Cost
1 credit per new Short Address — no Short Address, or the same address again within 7 days, is free
What's new
  • Every map link — Google Maps pins, places and businesses, links copied from the browser, Apple Maps, Waze, OpenStreetMap. Input types
  • Always an answer — no Short Address on the exact point returns the nearest registered building's within 100 m, flagged in nearest. Response
  • Search by place name — GET /api/v1/search, then look up the place_id. Name search
  • Fair billing — you pay only for new addresses found. Credits

Authentication

Every request must carry your secret API key in the X-API-Key header. You can also use Authorization: Bearer <key>.

HTTP header
X-API-Key: sat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
🔑

Your key is shown once, when you generate it in the Console → API tab. We store only a hashed version, so we can never show it again. Lost it? Regenerate — the old key stops working instantly. Keys are secret: keep them on your server, never in a mobile app or browser.

The lookup endpoint

POST /api/v1/lookup

Send a JSON body with an input and an optional language.

FieldTypeRequiredDescription
inputstringYesCoordinates "24.71,46.67" or a Short Address "RCDA6608".
languagestringNo"en" (default) or "ar".

Input types

📍

Coordinates

Latitude, longitude. "24.7136, 46.6753". Returns the full national address incl. the Short Address.

🏷️

Short Address

The 8-char Saudi code. "RCDA6608". Resolves to coordinates + full address.

🔗

Map links

Google Maps (short and full links, dropped pins, links copied from the browser), Apple Maps, Waze, OpenStreetMap, HERE, Bing and Petal links, plus degrees-minutes-seconds and plus codes.

🏪

Google place links

A shop, office or area shared from Google Maps without a pin is placed on Google's own location for that place, then looked up like a pin.

Response

A 200 OK returns the structured address. Fields that can't be resolved are null.

200 OK · application/json
{
  "short_address":     "RCDA6608",
  "formatted":         "Al Aqiq, Riyadh 13515, Saudi Arabia",
  "building_number":   "6608",
  "street":            "Anas Ibn Malik Road",
  "district":          "Al Aqiq",
  "city":              "Riyadh",
  "region":            "Riyadh",
  "postal_code":       "13515",
  "additional_number": "2745",
  "country":           "Saudi Arabia",
  "lat":               24.7563,
  "lng":               46.6295,
  "resolved_via":      "national_address",
  "cached":            false,
  "credits_remaining": 4871,
  "input":             "24.7563, 46.6295"
}

When the pin is not on a registered building

A Short Address belongs to a registered building. If the point is on a street, a car park or open land, you get the Short Address of the nearest registered building within 100 m, and two extra fields say so. Beyond 100 m, short_address is null and no credit is used.

{
  "short_address":      "RRRA3218",
  "nearest": {
    "short_address":    "RRRA3218",
    "distance_m":       23,
    "lat":              24.87922,
    "lng":              46.62253
  },
  "short_address_note": "Nearest registered building, 23 m from this point",
  "lat":                24.8791221,
  "lng":                46.6227282,
  "...":                "the other fields describe that building"
}

cached: true means the result was served from our cache — it still counts as one credit but returns in milliseconds. credits_remaining is null for bring-your-own-key accounts.

Code examples

curl -X POST https://your-host/api/v1/lookup \
  -H "X-API-Key: sat_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": "24.7136, 46.6753", "language": "en"}'

Batch lookups

Have a long list? Send up to 1,000 inputs in one request instead of one request each. The batch is looked up in the background at a steady pace, and you collect the results when it's done. Billing is the same as the bulk CSV: 1 credit per new Short Address found; inputs with no Short Address, repeats and errors are free.

POST /api/v1/batch
curl -X POST https://your-host/api/v1/batch \
  -H "X-API-Key: sat_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"inputs": ["24.7563,46.6295", "RCDA6608", "https://maps.app.goo.gl/..."], "language": "en"}'

The answer is 202 Accepted with a batch_id:

{
  "batch_id": "3f9c2a7d41e0b8c65d12",
  "status":   "queued",
  "total":    3,
  "done":     0
}
GET /api/v1/batch/{batch_id}

Ask every few seconds. While status is queued or running you see the progress (done of total). When it is done, results lists every input in the order you sent it, with the address fields of a single lookup plus status (it starts with ok when the address was found) and error.

{
  "batch_id": "3f9c2a7d41e0b8c65d12",
  "status":   "done",
  "total": 3, "done": 3, "ok": 2, "errors": 1, "skipped": 0,
  "results": [
    {"input": "24.7563,46.6295", "status": "ok", "short_address": "RCDA6608",
     "building_number": "6608", "street": "Anas Ibn Malik Road", "district": "Al Aqiq",
     "city": "Riyadh", "postal_code": "13515", "additional_number": "2745", "...": "..."},
    {"input": "RCDA6608", "status": "ok - free, already looked up", "...": "..."},
    {"input": "https://maps.app.goo.gl/...", "status": "error",
     "error": "This link shares a place name, not a pin on the building...", "...": "..."}
  ]
}

Stop a batch with POST /api/v1/batch/{batch_id}/cancel — inputs not looked up yet use no credit. Results stay available for 7 days. Errors: 400 inputs_required, 413 too_many_rows (over 1,000 inputs), 402 insufficient_credits (your balance is lower than the number of inputs), 429 queue_full (10,000 inputs already waiting).

Errors

Errors return a non-2xx status and a JSON body with an error code and human-readable message.

StatuserrorMeaning
400input_requiredMissing or unparseable input.
401api_key_required / invalid_api_keyMissing key, or the key is wrong / API access disabled.
402out_of_creditsYour credit balance is 0. Top up to continue.
403account_suspendedThe account is suspended.
429rate_limitedToo many requests — see Retry-After header.
502lookup_failedNo provider could resolve the point. No credit is charged.

You are only charged for successful lookups. Failed and invalid requests never consume a credit.

Rate limits

The API allows up to 120 requests per minute per account. Exceeding it returns 429 with a Retry-After header (seconds). For a long list, send a batch of up to 1,000 inputs instead. Repeated identical lookups are served from cache and are much faster.

Credits & billing

You pay only for new addresses. 1 credit is used when a lookup returns a Short Address you haven't looked up recently. These are free:

  • a lookup that finds no Short Address (no building within 100 m) — the response says "charged": false
  • the same Short Address again within 7 days (free_reason: "repeat")
  • place-name suggestions from /api/v1/search

The web app, bulk CSV and API draw from the same shared balance. Buy credit packs in the Console → Billing tab. Watch credits_remaining in each response, and top up before you hit zero to avoid 402 errors.

Security best practices

  • Call the API from your backend server only. Never embed the key in a mobile app, browser JavaScript, or public repo.
  • Store the key in an environment variable / secrets manager — not in source code.
  • Always use HTTPS (the API rejects plain HTTP at the proxy).
  • Rotate the key immediately if you suspect it leaked — regenerating instantly invalidates the old one.
  • Disable API access from the Console when you're not using it; the key is preserved and can be re-enabled anytime.

Ready to integrate?

Generate your key in the console and make your first call in minutes.

Open Console →