Skip to content

Onboarding

Ivan William edited this page Aug 29, 2026 · 1 revision

Onboarding

Getting Started with SATUSEHAT Integration

This guide walks you through setting up your development environment, obtaining SATUSEHAT credentials, and sending your first API request.


Prerequisites

  1. SATUSEHAT Developer Account — register at https://developer.satusehat.kemkes.go.id
  2. PHP 7.4+ or PHP 8.x installed
  3. Composer installed
  4. Internet access to reach SATUSEHAT APIs

Step 1: Register as a SATUSEHAT Developer

  1. Go to https://developer.satusehat.kemkes.go.id
  2. Create an account / log in
  3. Navigate to Integration → New Application
  4. Create a new application with a name (e.g. "My FHIR App")
  5. You will receive:
    • Client ID
    • Client Secret
  6. For each environment (DEV / STG / PROD), register your application separately

Step 2: Register Your Organization

For non-production environments, SATUSEHAT provides sandbox organization IDs.

DEV Environment comes pre-seeded with test organization IDs. You can use the provided dev practitioner and patient IDs directly.

For STG and PROD, register your actual organization in the SATUSEHAT portal and obtain the official organization_id.


Step 3: Install the Library

composer require ivanwilliammd/satusehat-integration

Step 4: Configure Environment Variables

Create a .env file in your project root:

# Choose environment: DEV | STG | PROD
SATUSEHAT_ENV=DEV

# DEV environment credentials
SATUSEHAT_BASE_URL_DEV=https://api-satusehat-dev.dto.kemkes.go.id
CLIENTID_DEV=your_client_id_from_portal
CLIENTSECRET_DEV=your_client_secret_from_portal
ORGID_DEV=your_organization_id

# STG environment credentials
SATUSEHAT_BASE_URL_STG=https://api-satusehat-stg.dto.kemkes.go.id
CLIENTID_STG=your_client_id_from_portal
CLIENTSECRET_STG=your_client_secret_from_portal
ORGID_STG=your_organization_id

# PROD environment credentials
SATUSEHAT_BASE_URL_PROD=https://api-satusehat.kemkes.go.id
CLIENTID_PROD=your_client_id_from_portal
CLIENTSECRET_PROD=your_client_secret_from_portal
ORGID_PROD=your_organization_id

Step 5: Run Migrations

If using Laravel:

php artisan migrate

For standalone PHP, create the required tables (see Installation page).


Step 6: Send Your First Request

Full Patient Creation Example

<?php
require_once __DIR__ . '/vendor/autoload.php';

use Satusehat\Integration\SSRequest\SSRequest;
use Satusehat\Integration\OAuth2Client;
use Satusehat\Integration\DataType\Identifier;
use Satusehat\Integration\DataType\HumanName;
use Satusehat\Integration\DataType\Address;
use Satusehat\Integration\DataType\ContactPoint;
use Satusehat\Integration\Builder\PayloadBuilderPatient;

// Initialize
$ss = new SSRequest(new OAuth2Client());

// Build a Patient resource
$patient = (new PayloadBuilderPatient)
    ->addIdentifier(new Identifier(
        system: 'https://fhir.kemkes.go.id/id/NIK',
        value: '3312345678901234'
    ))
    ->addName(new HumanName(
        family: 'Doe',
        given: ['John', 'Michael'],
        use: 'official'
    ))
    ->addTelecom(new ContactPoint(
        system: 'phone',
        value: '081234567890',
        use: 'mobile'
    ))
    ->addAddress(new Address(
        use: 'home',
        line: ['Jl. Sudirman No.1'],
        city: 'Jakarta Selatan',
        district: 'Kebayoran Baru',
        state: 'DKI Jakarta',
        postalCode: '12190',
        country: 'ID'
    ))
    ->setGender('male')
    ->setBirthDate('1990-01-15')
    ->setActive(true)
    ->build();

// Send to SATUSEHAT
$resp = $ss->post('Patient', $patient);

if ($resp->isSuccess()) {
    echo "SUCCESS! Patient ID: " . $resp->getResourceId() . "\n";
} else {
    echo "FAILED:\n";
    foreach ($resp->getErrorMessages() as $msg) {
        echo "  - $msg\n";
    }
}

Step 7: Search for Existing Resources

// Search by NIK
$resp = $ss->get('Patient', [
    'identifier' => 'https://fhir.kemkes.go.id/id/NIK|3312345678901234'
]);

// Search by name
$resp = $ss->get('Patient', [
    'name' => 'Doe',
    'birthdate' => '1990-01-15'
]);

// Get a specific patient
$resp = $ss->get('Patient/12345678-1234-1234-1234-123456789012');

Understanding SATUSEHAT Environments

Environment Purpose Base URL
DEV Development & testing https://api-satusehat-dev.dto.kemkes.go.id
STG Staging / pre-production https://api-satusehat-stg.dto.kemkes.go.id
PROD Production https://api-satusehat.kemkes.go.id

Environment Behavior Differences

  • DEV — Faster validation, test data available. Token never truly expires.
  • STG — Near-production behavior, real validation rules enforced.
  • PROD — Full validation, real patient data. Rate limits apply strictly.

Switching Environments

Simply change SATUSEHAT_ENV in your .env and update the corresponding credentials:

// Or override at runtime:
$oauth2 = new OAuth2Client();
$oauth2->satusehat_env = 'STG';
$oauth2->base_url = 'https://api-satusehat-stg.dto.kemkes.go.id';
$oauth2->fhir_url = 'https://api-satusehat-stg.dto.kemkes.go.id/fhir-r4/v1';
$oauth2->client_id = 'your_stg_client_id';
$oauth2->client_secret = 'your_stg_client_secret';
$oauth2->organization_id = 'your_stg_org_id';

Common Terminology Systems

System Use Case
https://fhir.kemkes.go.id/id/NIK Indonesian National ID (NIK/KTP)
https://fhir.kemkes.go.id/id/KTP KTP identifier
http://terminology.hl7.org/CodeSystem/v3-ActCode Encounter class codes
http://terminology.hl7.org/CodeSystem/condition-clinical Condition clinical status
http://hl7.org/fhir/sid/icd-10 ICD-10 diagnosis codes
http://sys-ids.kemkes.go.id/kfa KFA drug codes
http://loinc.org LOINC observation codes
http://snomed.info/sct SNOMED CT terminology
http://unitsofmeasure.org UCUM units of measure
http://www.whocc.no/atc ATC drug classification

Development Tips

Test Credentials

DEV environment provides pre-seeded test practitioner and patient IDs. Check OAuth2Client:

$oauth2 = new OAuth2Client();
print_r($oauth2->practitioner_dev); // Array of test practitioner IDs
print_r($oauth2->patient_dev);      // Array of test patient IDs

Enable Detailed Logging

$ss = new SSRequest($oauth2, config: [
    'log_enabled' => true,
]);

Handle Rate Limits

The library handles 429 automatically. For high-volume scenarios, use the queue worker:

use Satusehat\Integration\Queue\SqliteQueue;
use Satusehat\Integration\Queue\Worker;
use Satusehat\Integration\Queue\RateLimiter;

$queue = new SqliteQueue(new PDO('sqlite:' . __DIR__ . '/queue.db'));
$worker = new Worker($queue, [...], new RateLimiter(300)); // 300 RPM
$worker->process(100);

Next Steps