API

API keys

Mint, list, and revoke the machine API keys that authenticate every request — nk_live_ and nk_sandbox_, scoped, shown once.

An API key is how your infrastructure authenticates — a secret in a server env var, not a user login. This page covers minting, listing, and revoking keys over the API. For how keys travel on requests and what sandbox vs. live means, see Authentication.

Key prefixes#

Every key is bound to one environment, and you can tell which from its prefix:

Prefix Environment Resolves to
nk_live_… Live Real patients and pharmacies (requires an active agreement).
nk_sandbox_… Sandbox Synthetic patients + a mock pharmacy.

Keep every key server-side. Never ship one in a browser, a mobile app, or client-side code.

The secret is shown once#

When you create a key, the plaintext key is returned exactly once, in the create response, and is never retrievable again. neolife stores only a hash. Capture it at creation time and put it straight into your secret store. If you lose it, you revoke the key and mint a new one — there is no "reveal" endpoint.

Create a key#

curl -X POST https://api.neolife.health/v1/developer/keys \
  -H "Authorization: Bearer $NEOLIFE_API_KEY" \
  -H "Idempotency-Key: 8c2f0a1e-4b7d-4e33-9a6c-2d1f5b8e0c74" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "shopify-fulfillment-worker",
    "environment": "sandbox",
    "scopes": ["orders:write", "orders:read"]
  }'
  • name — a human label so you can tell keys apart in the list.
  • environmentsandbox or live. Determines the prefix you get back.
  • scopes — optional. Omit for a full-access key; include one or more scopes to mint a restricted key. A restricted key with an empty scope list is rejected with 400.

The response returns the plaintext key alongside the public representation:

{
  "key": "nk_sandbox_9f3c1a7e2b8d4056a1c9e7f30d2b6a84",
  "apiKey": {
    "id": "key_7Qw2eR",
    "name": "shopify-fulfillment-worker",
    "environment": "sandbox",
    "prefix": "nk_sandbox_9f3c1a7e",
    "scopes": ["orders:write", "orders:read"],
    "createdAt": "2026-07-06T14:12:00Z",
    "revokedAt": null
  }
}

apiKey.prefix is a non-secret fragment you can safely log or display to identify a key later. The full key is the only field you can't fetch again.

Creating a key is a mutation, so send an Idempotency-Key. A retried create with the same key replays the original response instead of minting a second key.

Scopes#

A key can be full-access or restricted to a set of scopes. Scope your keys to the least privilege the integration needs — a webhook-processing worker that only reads orders doesn't need write access.

Scope Grants
orders:read Read orders and their status.
orders:write Create, approve, and submit orders.
intake:read / intake:write Read and manage compliance intake.
catalog:read Read your formulary.
webhooks:manage Manage webhook endpoints.

A call made with a key that lacks the required scope returns 403. See Errors for the full status table.

List keys#

Returns the public (non-secret) representation of every key on your tenant, newest first. Plaintext secrets are never included.

curl https://api.neolife.health/v1/developer/keys \
  -H "Authorization: Bearer $NEOLIFE_API_KEY"
[
  {
    "id": "key_7Qw2eR",
    "name": "shopify-fulfillment-worker",
    "environment": "sandbox",
    "prefix": "nk_sandbox_9f3c1a7e",
    "scopes": ["orders:write", "orders:read"],
    "createdAt": "2026-07-06T14:12:00Z",
    "revokedAt": null
  }
]

Revoke a key#

Revocation is irreversible and takes effect immediately — the next request made with a revoked key fails authentication. It's also idempotent: revoking an already-revoked key is a no-op that returns the same key, and revoking a key that doesn't exist on your tenant returns 404.

curl -X DELETE https://api.neolife.health/v1/developer/keys/key_7Qw2eR \
  -H "Authorization: Bearer $NEOLIFE_API_KEY"
{
  "id": "key_7Qw2eR",
  "name": "shopify-fulfillment-worker",
  "environment": "sandbox",
  "prefix": "nk_sandbox_9f3c1a7e",
  "scopes": ["orders:write", "orders:read"],
  "createdAt": "2026-07-06T14:12:00Z",
  "revokedAt": "2026-07-06T16:40:00Z"
}

Rotating a key#

There's no in-place rotation — rotate by creating the replacement, then revoking the old one:

  1. Create a new key with the same environment and scopes.
  2. Deploy the new key to your secret store and roll it out.
  3. Revoke the old key once nothing is using it.

Because create and revoke are independent calls, you get a clean overlap window with no downtime.

Related#

  • Authentication — how keys travel on requests, sandbox vs. live, and least-privilege guidance.
  • API reference — base URL, versioning, errors, and rate limits.