Developer guide · current app behavior

Oathpin integration guide

Understand the credential workflows available to healthcare teams today, and where a direct system integration is not yet available.

Oathpin API docs

What integrations can do today

Available today

Signed-in Oathpin users can manage credential records. Organization managers can review organization credential data and export a scoped CSV. Signed-in users can also save webhook endpoint settings.

Not available in this checkout

There is no partner API credential or OAuth client flow, automated HR/EHR/EMR sync, FHIR or HL7 endpoint, or delivery of selected credential and document webhook events. Protected webhook settings can send a one-off signed webhook.test event to verify a destination. The internal POLSIA_API_KEY is for Oathpin platform proxy calls and is not an integration credential.

Fit for HR, EHR, EMR, and practice management

HR and workforce systems

A manager can export an organization credential register as CSV for an existing workforce process. The receiving team must map and import that file themselves; scheduled sync and employee provisioning are not exposed here.

EHR and EMR systems

The current app has no EHR/EMR connector, FHIR resource endpoint, HL7 feed, or partner credential for machine-to-machine access. Do not treat the app routes below as a clinical-system API.

Practice-management systems

Organization managers can use the same scoped CSV handoff for practice compliance workflows. There is no direct practice-management connector or automatic roster/credential synchronization.

Healthcare workflow examples

The HR and practice-management requests below are in-app, session-authenticated operations. They require an active paid subscription and an organization owner orcompliance_admin role. They are not partner API requests. This public documentation page remains ungated.

HR

An organization owner or compliance_admin can request a CSV for a manual workforce handoff. The receiving team maps and imports it into its existing process; this route does not provide scheduled sync or employee provisioning.

In-app request · session-authenticated

GET /api/organization/credentials/export?organizationId=org_example_001
CSV export wrapper · illustrative response
{
  "ok": true,
  "data": {
    "filename": "organization-credentials.csv",
    "records": 1,
    "csv": "Illustrative polsia-csv-v2 output; CSV cells are text-protected by the export module."
  }
}

EHR

This checkout has no FHIR or HL7 endpoint, partner API credential or OAuth flow, or direct EHR connector. It does not exchange patient or chart data or synchronize automatically.

EMR

This checkout has no FHIR or HL7 endpoint, partner API credential or OAuth flow, or direct EMR connector. It does not exchange patient or chart data or synchronize automatically.

Practice management

An organization owner or compliance_admin can review the organization-scoped credential register and its summary for a compliance workflow. The projection includes only a masked credential reference and does not return supporting documents or raw credential numbers.

In-app request · session-authenticated

GET /api/organization/credentials?organizationId=org_example_001
Credential register · illustrative response
{
  "items": [
    {
      "id": "orgcred_example_001",
      "providerUserId": "user_example_001",
      "providerName": "Alex Example",
      "providerEmail": "alex@example.test",
      "credentialId": "cred_example_001",
      "credentialName": "Registered Nurse License",
      "credentialReferenceMasked": "••••4821",
      "credentialType": "state_id",
      "credentialStatus": "current",
      "expiresAt": "2027-01-15T00:00:00.000Z",
      "issuingBody": "Example State Board of Nursing",
      "verificationStatus": "verified",
      "documentReadiness": "ready"
    }
  ],
  "summary": {
    "totalCredentials": 1,
    "verifiedCredentials": 1,
    "missingDocuments": 0,
    "expiringSoon": 0
  }
}

Authentication and access

The current app routes use Better Auth session cookies. They are signed-in workspace APIs for Oathpin users, not public partner endpoints. A browser session cookie must come from the app’s own sign-in flow; there is no documented bearer token, API key, service account, or OAuth client-credentials grant for partners.

Credential routes and webhook settings also require an active paid subscription. Organization credential reads, CSV export, and organization-scoped webhook settings require an organization manager: an owner or compliance_admin. A regular organization member cannot use those manager-only operations.

Keep cookies in the authenticated browser session and never copy the internal POLSIA_API_KEY into an integration. This documentation page is public and does not require a session.

Current route access: Better Auth session cookie + active paid subscription.
Organization data: owner or compliance_admin role.
Partner API key / OAuth client credentials: not available.

Credential record flow

A signed-in provider can submit a credential record with its name, type, issuing body, credential number, jurisdiction, issue date, and expiration date. The create route returns the new record ID with HTTP 201.

The provider credential list returns a summary: record ID, name, type, issuing body, expiration, status, and verification status. It does not return the raw credential number. Organization views expose a masked credential reference, not the raw number or a supporting document.

These examples describe the current in-app workflow. They do not define an external provider import, update, or synchronization API.

Create a credential · illustrative requestPOST /api/credentials · 201 Created
{
  "name": "Registered Nurse License",
  "type": "state_id",
  "issuingBody": "Example State Board of Nursing",
  "credentialNumber": "EXAMPLE-RN-4821",
  "jurisdiction": "Example State",
  "issueDate": "2024-01-15",
  "expirationDate": "2027-01-15"
}
Create response
{
  "id": "cred_example_001"
}
List response · GET /api/credentials
{
  "items": [
    {
      "id": "cred_example_001",
      "name": "Registered Nurse License",
      "type": "state_id",
      "issuingBody": "Example State Board of Nursing",
      "expiresAt": "2027-01-15T00:00:00.000Z",
      "status": "active",
      "verificationStatus": "unverified"
    }
  ],
  "counts": {
    "active": 1,
    "expiringSoon": 0,
    "expired": 0,
    "missingDocuments": 0
  }
}

Organization register and CSV handoff

Organization managers can read the organization credential register or request the current CSV handoff. Both operations are scoped to an organization and require a paid signed-in account plus an owner or compliance_admin role.

The CSV contains provider name and email, credential name and type, issuing body, expiration, credential status, verification status, and document readiness. It excludes raw credential numbers and supporting documents.

Exports are capped at 10,000 rows and 10 MiB. The API returns a JSON wrapper using the polsia-csv-v2 format; its data.csv field contains CSV text and data.records reports the exported row count.

Organization credential list · illustrative responseGET /api/organization/credentials?organizationId=org_example_001
{
  "items": [
    {
      "id": "orgcred_example_001",
      "providerUserId": "user_example_001",
      "providerName": "Alex Example",
      "providerEmail": "alex@example.test",
      "credentialId": "cred_example_001",
      "credentialName": "Registered Nurse License",
      "credentialReferenceMasked": "••••4821",
      "credentialType": "state_id",
      "credentialStatus": "current",
      "expiresAt": "2027-01-15T00:00:00.000Z",
      "issuingBody": "Example State Board of Nursing",
      "verificationStatus": "verified",
      "documentReadiness": "ready"
    }
  ],
  "summary": {
    "totalCredentials": 1,
    "verifiedCredentials": 1,
    "missingDocuments": 0,
    "expiringSoon": 0
  }
}
CSV export wrapper · illustrative responseGET /api/organization/credentials/export?organizationId=org_example_001
{
  "ok": true,
  "data": {
    "filename": "organization-credentials.csv",
    "records": 1,
    "csv": "Illustrative polsia-csv-v2 output; CSV cells are text-protected by the export module."
  }
}

Webhook endpoint settings

The signed-in settings API can list, create, enable or disable, and delete account- or organization-scoped endpoint configuration. Create accepts an HTTPS URL and one or more known event names. Organization scope requires an organization manager.

A successful create returns the signing secret once. Later endpoint projections include only a masked secret. Store the one-time value securely if you create an endpoint.

From Settings → Webhooks, Send test calls POST /api/webhooks/test for one endpoint. The request includes its endpoint ID and account or organization scope; the server loads the signing secret and sends one webhook.test request even when the endpoint is disabled or has no selected business events. The browser never receives the secret or signature.

The test body is JSON with id, type, createdAt, and data.message. It includes X-Oathpin-Event: webhook.test and X-Oathpin-Signature: sha256=<hex HMAC-SHA256 of the exact raw body>. The request has a 10-second timeout, does not follow redirects, and accepts only receiver 2xx responses. There are no automatic retries or delivery history.

This is only a settings verification request. Selected credential and document events remain undispatched; their delivery timing, ordering, retry behavior, idempotency, timestamp or replay handling, and secret-rotation contract are not defined.

Create organization endpoint · illustrative requestPOST /api/webhooks · 201 Created
{
  "scope": "organization",
  "organizationId": "org_example_001",
  "url": "https://receiver.example.test/oathpin",
  "eventTypes": [
    "credential.created",
    "document.updated"
  ]
}
Create response · secret shown once
{
  "item": {
    "id": "webhook_example_001",
    "scope": "organization",
    "organizationId": "org_example_001",
    "url": "https://receiver.example.test/oathpin",
    "eventTypes": [
      "credential.created",
      "document.updated"
    ],
    "enabled": true,
    "signingSecretMasked": "••••••••••••ABCD",
    "createdAt": "2026-09-29T12:00:00.000Z",
    "updatedAt": "2026-09-29T12:00:00.000Z"
  },
  "signingSecret": "example-only-secret-ABCD"
}
Later list response · secret maskedGET /api/webhooks?scope=organization&organizationId=org_example_001
{
  "items": [
    {
      "id": "webhook_example_001",
      "scope": "organization",
      "organizationId": "org_example_001",
      "url": "https://receiver.example.test/oathpin",
      "eventTypes": [
        "credential.created",
        "document.updated"
      ],
      "enabled": true,
      "signingSecretMasked": "••••••••••••ABCD",
      "createdAt": "2026-09-29T12:00:00.000Z",
      "updatedAt": "2026-09-29T12:00:00.000Z"
    }
  ]
}

Webhook event reference

The names below are accepted when saving endpoint settings but do not mean the current app emits those business events. webhook.test is sent only when a signed-in user triggers Send test in protected settings.

Event names accepted by settings

  • credential.created
  • credential.updated
  • document.created
  • document.updated
  • credential.primary_source_verification_decided
  • credential.primary_source_verification_recorded

Settings-only test payload

The manual test event uses { id, type: "webhook.test", createdAt, data: { message: "This is a test event from Oathpin webhook settings." } }. It is independent of the endpoint event selections and enabled state.

Business event delivery is not available

For this test request only, the exact JSON body is signed with the endpoint secret using HMAC-SHA256 and sent in X-Oathpin-Signature; X-Oathpin-Event labels the request. Redirects are not followed, only a 2xx response is success, and response bodies are not returned. Enabled endpoints do not receive credential or document event requests in this checkout.

Endpoint configuration examples are shown separately in Webhook endpoint settings; they are not event delivery requests or payloads.

Open protected webhook settings requires a signed-in Oathpin account with an active paid subscription.

Example conventions

Every ID, person, email, date, credential number, secret, and endpoint shown here is illustrative. example.test and receiver.example.test are reserved example hosts; do not send real data to them. Requests require the current app session and paid access described above. These are in-app route examples, not a partner service API specification.

Credential create accepts the fields shown in its example. The list response reports a status summary, while the organization list/export use their own organization-scoped shapes. Keep the masked organization reference masked; these routes do not provide a raw credential number or document download in the shown projections.

Errors and access boundaries

These statuses are returned by the routes documented here. The exact message varies by route and failure; validation responses use an errors object, while access and limit failures use an error string.

400
Invalid JSON or a request/query field that fails validation; the response uses an errors map.
401
The request has no valid signed-in session.
402
The account does not have the paid subscription required by the route.
403
The user lacks access to the organization or its manager-only operation.
404
The organization or scoped webhook endpoint does not exist.
413
An organization CSV export exceeds the row or byte limit.
Validation error · example
{
  "errors": {
    "credentialNumber": "Credential number is required"
  }
}
Unauthenticated · example
{
  "error": "Unauthorized"
}
Paid access required · example
{
  "error": "subscription_required"
}
Organization manager required · example
{
  "error": "Organization credentials are restricted to organization managers"
}
Missing organization · example
{
  "error": "Organization not found"
}
CSV row limit · example
{
  "error": "Export exceeds the 10,000 row limit"
}