Area API

Test on Postman

Read-only lookup endpoints for Indonesian administrative regions (Province, City, District, Village).

API ENVIRONMENT

Endpoint

GET
Provinceshttps://sandbox.ipaymu.com/api/areas/province
GET
Citieshttps://sandbox.ipaymu.com/api/areas/city/{province}
GET
Districtshttps://sandbox.ipaymu.com/api/areas/district/{city}
GET
Villageshttps://sandbox.ipaymu.com/api/areas/village/{district}

Use credentials from the selected environment. Sandbox and Production credentials are separate.

Read-only lookup endpoints for Indonesian administrative regions: Province → City → District → Village. Typically used to populate cascading dropdowns (e.g. address forms, verification, shipping).

The list is hierarchical: pick a province to get its cities, pick a city to get its districts, and so on. Each endpoint returns the region code used as the parameter for the next level down.


Base URL

EnvironmentBase URL
Productionhttps://my.ipaymu.com/api
Sandboxhttps://sandbox.ipaymu.com/api
ⓘ

Adjust to your deployment. Locally this maps to {APP_URL}/api.

All Area endpoints are under the /areas prefix.


Authentication

Every request must be signed. The signature middleware (signaturecheck) requires these HTTP headers:

HeaderRequiredTypeExample / valueDescription
va✅ YesstringYOUR_IPAYMU_VAVirtual Account number (baccount) from the Integration menu in Production or Sandbox. Use the VA for the request environment.
signature✅ Yesstring (64 hexadecimal characters)GENERATED_SIGNATUREHMAC-SHA256 value for this request (see below), generated with the API Key from Production or Sandbox. Do not send the API Key as this header value.
timestampRecommendedstring (14 digits)20260102153045Request time in YYYYMMDDHHmmss format (2 January 2026 at 15:30:45).
Content-Type✅ Yesstringapplication/jsonMIME type for the JSON request.

The account tied to the va must be active and have an API key.

Signature generation

requestBody  = lowercase( sha256( <raw request body> ) )
stringToSign = <HTTP_METHOD> + ":" + <VA> + ":" + requestBody + ":" + <API_KEY>
signature    = hmac_sha256( stringToSign, <API_KEY> )

Notes:

  • <HTTP_METHOD> must be upper-case (GET).
  • For requests without a body (all Area GET endpoints), use the empty JSON object {} as the body when hashing — i.e. requestBody = sha256("{}").
  • <API_KEY> is used both as part of stringToSign and as the HMAC secret key.

Example Signature Code

const crypto = require('crypto');

const va = 'YOUR_IPAYMU_VA';
const apiKey = 'YOUR_API_KEY';
const method = 'GET';

const body = '{}';
const requestBody = crypto.createHash('sha256').update(body).digest('hex').toLowerCase();
const stringToSign = `${method}:${va}:${requestBody}:${apiKey}`;
const signature = crypto.createHmac('sha256', apiKey).update(stringToSign).digest('hex');
const timestamp = new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14);

Response envelope

All responses share the same wrapper:

{
  "Status": 200,
  "Success": true,
  "Message": "Success",
  "Data": []
}
FieldTypeDescription
StatusintegerHTTP status code, mirrored in the body.
Successbooleantrue on success, false on error.
MessagestringHuman-readable message.
Dataarray | nullResult payload (an array of region objects).

Endpoints

1. Get Provinces

Returns all provinces, ordered by name (A→Z).

GET /areas/province

Parameters: none

Example request

curl --location 'https://sandbox.ipaymu.com/api/areas/province' \
  --header 'Content-Type: application/json' \
  --header 'va: YOUR_IPAYMU_VA' \
  --header 'signature: <generated-signature>' \
  --header 'timestamp: 20260629103000'

Example response 200 OK

{
  "Status": 200,
  "Success": true,
  "Message": "Success",
  "Data": [
    { "code": "11", "name": "ACEH" },
    { "code": "51", "name": "BALI" },
    { "code": "36", "name": "BANTEN" }
  ]
}

2. Get Cities by Province

Returns the cities/regencies belonging to a province.

GET /areas/city/{province}

Path parameters

ParamTypeDescription
provincestringProvince code (from the Provinces endpoint).

Example request

curl --location 'https://sandbox.ipaymu.com/api/areas/city/51' \
  --header 'Content-Type: application/json' \
  --header 'va: YOUR_IPAYMU_VA' \
  --header 'signature: <generated-signature>' \
  --header 'timestamp: 20260629103000'

Example response 200 OK

{
  "Status": 200,
  "Success": true,
  "Message": "Success",
  "Data": [
    { "code": "5171", "name": "KOTA DENPASAR" },
    { "code": "5103", "name": "KABUPATEN BADUNG" }
  ]
}

3. Get Districts by City

Returns the districts (kecamatan) belonging to a city.

GET /areas/district/{city}

Path parameters

ParamTypeDescription
citystringCity code (from the Cities endpoint).

Example request

curl --location 'https://sandbox.ipaymu.com/api/areas/district/5171' \
  --header 'Content-Type: application/json' \
  --header 'va: YOUR_IPAYMU_VA' \
  --header 'signature: <generated-signature>' \
  --header 'timestamp: 20260629103000'

Example response 200 OK

{
  "Status": 200,
  "Success": true,
  "Message": "Success",
  "Data": [
    { "code": "517101", "name": "DENPASAR SELATAN" },
    { "code": "517102", "name": "DENPASAR TIMUR" }
  ]
}

4. Get Villages by District

Returns the villages (kelurahan/desa) belonging to a district. Village objects also include a postal code.

GET /areas/village/{district}

Path parameters

ParamTypeDescription
districtstringDistrict code (from the Districts endpoint).

Example request

curl --location 'https://sandbox.ipaymu.com/api/areas/village/517101' \
  --header 'Content-Type: application/json' \
  --header 'va: YOUR_IPAYMU_VA' \
  --header 'signature: <generated-signature>' \
  --header 'timestamp: 20260629103000'

Example response 200 OK

{
  "Status": 200,
  "Success": true,
  "Message": "Success",
  "Data": [
    { "code": "5171011001", "name": "SANUR", "postal_code": "80227" },
    { "code": "5171011002", "name": "RENON", "postal_code": "80226" }
  ]
}

Field reference

Province / City / District

FieldTypeDescription
codestringRegion code. Use it as the path parameter for the next level.
namestringRegion name.

Village (same as above, plus)

FieldTypeDescription
postal_codestring | nullPostal code (null if unavailable).

Error responses

On authentication failure the request is rejected before reaching the controller:

StatusMessageCause
401invalid header param - va is requiredMissing va header.
401invalid header param - signature is requiredMissing signature header.
401unauthorized credentialva not found, inactive account, or no API key.
401unauthorized signatureSignature does not match.

Example error

{
  "Status": 401,
  "Success": false,
  "Message": "unauthorized signature",
  "Data": null
}
ⓘ

A valid request for a code that has no children (or an unknown code) returns 200 with an empty Data array ([]).


Notes

  • Method: Documented as GET. The routes accept any HTTP method, but use GET consistently so it matches the method used in your signature.
  • Caching: Region data is static; cache responses on the client to reduce calls.
  • Ordering: Provinces are returned A→Z by name. Cities, districts, and villages are returned in the database's natural order.

On this page