Modul Organization adalah titik awal setiap integrasi: kelola profil klien, sertifikat dan penandatangan default, pantau usage serta histori panggilan API, dan daftarkan NPWP tambahan ke kredensial kamu.
| Method | Path | Fungsi |
|---|---|---|
| GET | /v1/profile | Retrieve the authenticated client's profile |
| POST | /v1/profile | Update profile fields (partial update) |
| GET | /v1/usage | Inspect API usage and quota consumption |
| GET | /v1/histories | Retrieve history of past API calls |
| POST | /v1/organization | Register an additional NPWP |
The Organization module manages client-level configuration for an authenticated Sipajak account. It exposes the client's profile, usage and history of past API calls, and the ability to register additional NPWPs against an existing credential pair. New NPWPs must be registered through this module before they can appear in the npwp header of any other endpoint.
All endpoints in this module are scoped to the authenticated client. The npwp header still must be present on every request (it identifies which registered NPWP the call acts on behalf of), but the underlying data — profile, history rows, registered organisations — belongs to the client account as a whole, not to an individual NPWP.
4.1 Endpoint summary
| Method | Path | Purpose |
|---|---|---|
| GET | /v1/profile | Retrieve the authenticated client's profile |
| POST | /v1/profile | Update profile fields (partial update) |
| GET | /v1/usage | Inspect API usage and quota consumption |
| GET | /v1/histories | Retrieve history of past API calls |
| POST | /v1/organization | Register an additional NPWP |
4.2 Profile
The profile holds metadata about the authenticated client: contact information, certificate configuration for signing, signatory defaults, webhook configuration, and status flags. It is exposed through a single resource available via GET and POST on the same path.
4.2.1 Get profile
GET /v1/profile
Returns the authenticated client's profile.
Request headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | HTTP Basic Auth (see section 2.2) |
npwp | Yes | Active NPWP (see section 2.3) |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_send | boolean | No | When true, restricts the response to clients whose webhook endpoint is configured. Defaults to false. |
Example request
GET /v1/profile HTTP/1.1
Host: gateway-integration.sipajak.com
Authorization: Basic <base64-encoded credentials>
npwp: 1234567890123000Example response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"status_code": 200,
"message": "OK",
"data": {
"npwp": "1234567890123000",
"name": "PT Contoh Sejahtera",
"email": "contact@example.com",
"phone_number": "628120000000",
"address": "Jalan Contoh No. 1, Jakarta 12345",
"signatory_type": "INDIVIDUAL",
"signatory_name": "Budi Santoso",
"signatory_position": "Direktur",
"signatory_city": "Jakarta",
"status_efaktur": "ACTIVE",
"status_efaktur_message": null,
"webhook_url": null,
"webhook_key": null
}
}Response fields
| Field | Type | Description |
|---|---|---|
npwp | string | The NPWP for this profile (matches the npwp header) |
name | string | Legal name of the client |
email | string | Primary contact email |
phone_number | string | Contact phone (digits only, no formatting) |
address | string | Registered address |
signatory_type | string | Default signer type used on signed documents. One of INDIVIDUAL or ENTITY. |
signatory_name | string | Default signatory name |
signatory_position | string | Default signatory position |
signatory_city | string | City of signing |
status_efaktur | string | Current e-Faktur readiness status — ACTIVE when certificate and credentials are valid |
status_efaktur_message | string (nullable) | Additional context when status is not ACTIVE |
webhook_url | string (nullable) | Configured webhook destination for asynchronous events. Webhook delivery is on the roadmap. |
webhook_key | string (nullable) | Shared secret for webhook signature verification |
4.2.2 Update profile
POST /v1/profile
Updates one or more profile fields.
Partial-update semantics. Despite using HTTP POST, this endpoint performs a partial (PATCH-like) update. Only fields included in the request body are persisted; omitted fields are left unchanged. This is a Sipajak convention and may surprise REST-oriented clients expecting POST to mean full replacement.
When updating the signing certificate, the request must be sent as multipart/form-data with the certificate file under the field certificate_file. All other fields may then be sent as form fields. For non-certificate updates, plain application/json is accepted.
Request body — fields
| Field | Type | Description |
|---|---|---|
name | string | Legal name. Non-empty when provided. |
email | string | Valid email format. Non-empty when provided. |
phone_number | string | Digits only. Non-empty when provided. |
address | string | Registered address. Non-empty when provided. |
signatory_type | string | INDIVIDUAL or ENTITY |
signatory_name | string | Optional |
signatory_position | string | Optional |
signatory_city | string | Optional |
certificate_file | file (multipart) | DJP-issued signing certificate (.p12). Triggers a re-validation of status_efaktur. |
passphrase | string | Passphrase for the uploaded certificate. Required when certificate_file is included. |
webhook_url | string | HTTPS URL receiving webhook events |
webhook_key | string | Shared secret for HMAC signing of webhook payloads |
Example request
POST /v1/profile HTTP/1.1
Host: gateway-integration.sipajak.com
Authorization: Basic <base64-encoded credentials>
npwp: 1234567890123000
Content-Type: application/json
{
"phone_number": "628120000000",
"signatory_position": "Direktur Utama"
}The response is the same shape as GET /v1/profile, reflecting the updated state.
4.3 Usage
GET /v1/usage
Returns API usage and quota consumption for the authenticated client. Usage is calculated from a per-call billing journal: each chargeable API call contributes to the total according to a per-endpoint price. There is no static "quota limit" field — caps are enforced by Sipajak commercially and surfaced via this endpoint as cumulative consumption against the billing window.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | No | Start of the date range, inclusive. Format YYYY-MM-DD (ISO date). Defaults to the start of the current billing month when omitted. |
end_date | string | No | End of the date range, inclusive. Format YYYY-MM-DD. |
limit | string (numeric) | No | Pagination limit. Reserved — current implementation returns a single summary row. |
page | string (numeric) | No | Pagination page. Reserved. |
Example request
GET /v1/usage?start_date=2026-04-01&end_date=2026-04-30 HTTP/1.1
Host: gateway-integration.sipajak.com
Authorization: Basic <base64-encoded credentials>
npwp: 1234567890123000Example response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"status_code": 200,
"message": "OK",
"data": {
"start_date": "2026-04-01",
"end_date": "2026-04-30",
"total_calls": 12450,
"total_charged": 9876,
"total_price": 4938000,
"by_module": [
{ "module": "vswp", "calls": 8200, "charged": 6500, "price": 1300000 },
{ "module": "efaktur", "calls": 3100, "charged": 2800, "price": 2800000 },
{ "module": "ebupot", "calls": 1150, "charged": 576, "price": 838000 }
]
}
}Note. The exact response shape is subject to confirmation against staging. The example above reflects the documented contract of the underlying summary query. Fields total_calls, total_charged, and total_price represent the count of API calls made, the subset that incurred a charge (some lookups are cached or otherwise free), and the cumulative price in IDR rupiah respectively.
4.4 Histories
GET /v1/histories
Returns a paginated history of past API calls made by the authenticated client. Each row represents a single billable / DJP-bound request — Sipajak meta endpoints such as profile and usage are not currently captured in this history.
The most common use is to look up a specific past call by its correlation UUID — for debugging an integration issue or for retrieving the original request/response payload of a Faktur or Bupot submission days or weeks after the fact.
Query parameters
| Parameter | Type | Description |
|---|---|---|
code | string (uuid) | Filter to a single call by its correlation UUID. The UUID is returned in the response envelope of every DJP-bound API call (in fields such as data.uuid for VSWP, or as a top-level identifier on Faktur/Bupot responses). |
module_id | string | Filter by module identifier (vswp, efaktur, ebupot, etc.) |
endpoint_id | string | Filter by endpoint identifier |
status | string | SUCCESS or FAILED |
keyword | string | Free-text search across request/response payloads |
is_charge | boolean | Filter to charged-only or free-only calls |
limit | string (numeric) | Page size. Defaults to a server-controlled value if omitted. |
page | string (numeric) | Page number, 1-indexed |
Example — lookup by correlation UUID
GET /v1/histories?code=da862a83-c667-4e64-a20d-72b2ed70833c HTTP/1.1
Host: gateway-integration.sipajak.com
Authorization: Basic <base64-encoded credentials>
npwp: 1234567890123000Example response
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"status_code": 200,
"message": "OK",
"data": {
"items": [
{
"code": "da862a83-c667-4e64-a20d-72b2ed70833c",
"npwp": "1234567890123000",
"route": "/v2/vswp",
"module_id": "vswp",
"endpoint_id": "vswp.validate",
"status": "SUCCESS",
"is_charge": true,
"price": 200,
"history_date": "2026-05-08",
"created_time": "2026-05-08T10:23:45.123Z",
"request": "{\"npwp\":\"3201234567890000\",\"tujuan\":\"Validasi NPWP\"}",
"response": "{\"status\":\"1\",\"statusMessage\":\"Success\",\"result\":{...}}"
}
],
"total": 1,
"page": 1,
"limit": 10
}
}Row fields
| Field | Type | Description |
|---|---|---|
code | string (uuid) | Correlation UUID for this call — the same value returned in the original response envelope |
npwp | string | NPWP that issued the call |
route | string | API path called |
module_id | string | Module the call belongs to (vswp, efaktur, ebupot, etc.) |
endpoint_id | string | Endpoint identifier within the module |
status | string | SUCCESS or FAILED — based on the transport-level outcome |
is_charge | boolean | Whether the call counted against billing |
price | integer | Charge for this call in IDR rupiah (0 when is_charge is false) |
history_date | string (date) | Date of the call (YYYY-MM-DD) |
created_time | string (ISO 8601) | Precise timestamp |
request | string | JSON-stringified request body sent by the client |
response | string | JSON-stringified response body returned to the client |
Scope of capture. The histories endpoint captures DJP-bound and billable calls. Meta endpoints (/v1/profile, /v1/usage, /v1/histories itself, /v1/organization) are not stored here. To look up the full set of past calls including meta endpoints, contact the Sipajak API team — server-side audit logs can be consulted on request.
4.5 Register additional NPWP
POST /v1/organization
Registers an additional NPWP against the authenticated credential pair. After registration the new NPWP can be used in the npwp header on subsequent requests.
HTTP 201 on success. Unlike most Sipajak endpoints, a successful response from this endpoint returns HTTP 201 (Created), not 200. The envelope's status_code field reflects the same value.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
npwp | string | Yes | 15-digit legacy NPWP being registered |
npwp16 | string | No | 16-digit harmonised NPWP (NIK-based) if available |
nitku | string | No | NITKU (Nomor Identitas Tempat Kegiatan Usaha) if applicable |
name | string | Yes | Legal name of the organisation |
email | string | Yes | Primary contact email |
phone_number | string | Yes | Contact phone (digits only) |
address | string | Yes | Registered address |
logo | string | Yes | URL or base64 payload for the organisation logo |
type | string | Yes | Organisation type. One of INDIVIDUAL, COMPANY, GOVERNMENT, FOUNDATION. |
is_active | boolean | Yes | Whether this NPWP is immediately active for API calls |
is_government | boolean | No | Set to true for government entities subject to WAPU (Pemungut PPN) treatment |
parent_id | string | No | Parent organisation identifier for hierarchical groupings |
apj_name | string | Yes | Akuntan Publik / Penanggung Jawab — full name |
apj_position | string | Yes | Position / job title of the APJ |
apj_phone_number | string | Yes | APJ contact phone |
password | string | No | Optional sub-account password. Max length 50. |
Example request
POST /v1/organization HTTP/1.1
Host: gateway-integration.sipajak.com
Authorization: Basic <base64-encoded credentials>
npwp: 1234567890123000
Content-Type: application/json
{
"npwp": "2345678901234000",
"npwp16": "3201234567890000",
"name": "PT Contoh Sejahtera",
"email": "contact@example.com",
"phone_number": "628120000000",
"address": "Jalan Contoh No. 1, Jakarta 12345",
"logo": "https://cdn.example.com/logo.png",
"type": "COMPANY",
"is_active": true,
"is_government": false,
"apj_name": "Budi Santoso",
"apj_position": "Direktur",
"apj_phone_number": "628120000001"
}Example response — success
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8
{
"status_code": 201,
"message": "Created",
"data": {
"organization_id": "0192a3b4-c5d6-7890-abcd-ef1234567890",
"npwp": "2345678901234000",
"npwp16": "3201234567890000",
"name": "PT Contoh Sejahtera",
"type": "COMPANY",
"is_active": true,
"is_government": false,
"created_time": "2026-05-12T03:45:12.000Z"
}
}Example response — duplicate NPWP
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
{
"status_code": 400,
"message": "Bad Request Exception",
"error": "NPWP sudah terdaftar."
}Header NPWP on this endpoint. The npwp header on POST /v1/organization names an NPWP already registered to the credential — typically the client's primary organisation. The NPWP being newly registered is the value of body.npwp, not the header.
4.6 Error handling
| Situation | What the client sees |
|---|---|
| Successful read | HTTP 200, data carries the payload |
| Successful profile update | HTTP 200, data reflects updated state |
| Successful NPWP registration | HTTP 201, data carries the new organisation |
| Authentication failure | HTTP 401 |
| NPWP header missing or not registered | HTTP 403 |
| Validation error (missing required field, bad email format, bad phone format) | HTTP 400 with NestJS-style error envelope: { status_code: 400, message: "Bad Request Exception", error: ["validation messages"] } |
| Duplicate NPWP on registration | HTTP 400 with error "NPWP sudah terdaftar." |
| Server error | HTTP 500. Safe to retry with backoff. |