API REFERENCE v1

DEVELOPERS

API keys

The API key object

Secret keys (nc_…) and publishable keys (pk_…), full or restricted.

ATTRIBUTES

Show 6 more attributesHide 6 attributes
  • allowed_origins array of strings | null

    Publishable keys: origins allowed to call the public endpoints (null on secret keys).

  • token string | null

    Secret keys: only on creation, store it now. Publishable keys: always.

  • first_used_at string | null date-time

    First call made with this key (onboarding: waiting for your first event).

  • last_used_at string | null date-time
  • revoked_at string | null date-time
  • created_at string date-time

Schema: ApiKey

THE API KEY OBJECT
{
  "object": "api_key",
  "id": "key_GyLvx41FGQQBjCYX",
  "name": "CI",
  "kind": "secret",
  "mode": "test",
  "access": "full",
  "permissions": {
    "account": "write",
    "api_keys": "write",
    "team": "write",
    "events": "write",
    "customers": "write",
    "billing": "write",
    "stripe_connections": "write",
    "logs": "write",
    "flows": "write",
    "email_domains": "write",
    "messages": "write",
    "webhooks": "write",
    "cancel_sessions": "write",
    "reviews": "write",
    "dashboard": "write",
    "insights": "write",
    "integrations": "write",
    "queries": "write",
    "disputes": "write",
    "sandbox": "write"
  },
  "last4": "FLub",
  "allowed_origins": null,
  "token": "nc_test_EXAMPLE00000000000000000",
  "first_used_at": null,
  "last_used_at": null,
  "revoked_at": null,
  "created_at": "2026-11-04T10:00:00.000Z"
}

Create an API key (the token is returned once)

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): configure scope, test mode only.

BODY PARAMETERS

  • name string REQUIRED
  • mode enum

    Defaults to the current mode. A test key can only create test keys.

    • live
    • test
  • kind enum

    Default: secret. Publishable keys (pk_) are for the cancel widget.

    • secret
    • publishable
  • access enum

    Default: full. A key never creates a key more powerful than itself.

    • full
    • restricted
  • allowed_origins array of strings

    Publishable keys only: exact origins allowed to call the public endpoints. Left out, they default to https://<domain> and https://app.<domain> from the email of the user creating the key (else the account owner), unless it is a free or disposable mail domain. A list, even empty, is kept as given.

  • permissions object

    Restricted keys: level per resource (missing = none).

    Show child parametersHide child parameters

RETURNS

ERRORS

POST/v1/api_keys
curl https://api.nochurn.sh/v1/api_keys \
  -H "Authorization: Bearer nc_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI",
    "mode": "test"
  }'
const res = await fetch("https://api.nochurn.sh/v1/api_keys", {
  method: "POST",
  headers: {
    Authorization: "Bearer nc_test_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "CI",
    "mode": "test"
  }),
});
const apiKey = await res.json();
import requests

res = requests.post(
    "https://api.nochurn.sh/v1/api_keys",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
    json={
      "name": "CI",
      "mode": "test"
    },
)
api_key = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/api_keys")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
  "name" => "CI",
  "mode" => "test"
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
api_key = JSON.parse(res.body)
RESPONSE 201
{
  "object": "api_key",
  "id": "key_GyLvx41FGQQBjCYX",
  "name": "CI",
  "kind": "secret",
  "mode": "test",
  "access": "full",
  "permissions": {
    "account": "write",
    "api_keys": "write",
    "team": "write",
    "events": "write",
    "customers": "write",
    "billing": "write",
    "stripe_connections": "write",
    "logs": "write",
    "flows": "write",
    "email_domains": "write",
    "messages": "write",
    "webhooks": "write",
    "cancel_sessions": "write",
    "reviews": "write",
    "dashboard": "write",
    "insights": "write",
    "integrations": "write",
    "queries": "write",
    "disputes": "write",
    "sandbox": "write"
  },
  "last4": "FLub",
  "allowed_origins": null,
  "token": "nc_test_EXAMPLE00000000000000000",
  "first_used_at": null,
  "last_used_at": null,
  "revoked_at": null,
  "created_at": "2026-11-04T10:00:00.000Z"
}

Rename a key or change its access

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

BODY PARAMETERS

RETURNS

ERRORS

  • 403 forbidden more rights than the calling key
PATCH/v1/api_keys/{id}
curl https://api.nochurn.sh/v1/api_keys/key_mmRMLWbYwsDkVuTW \
  -X PATCH \
  -H "Authorization: Bearer nc_test_…" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "CI (read only)",
    "access": "restricted",
    "permissions": {
      "customers": "read"
    }
  }'
const res = await fetch("https://api.nochurn.sh/v1/api_keys/key_mmRMLWbYwsDkVuTW", {
  method: "PATCH",
  headers: {
    Authorization: "Bearer nc_test_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "CI (read only)",
    "access": "restricted",
    "permissions": {
      "customers": "read"
    }
  }),
});
const apiKey = await res.json();
import requests

res = requests.patch(
    "https://api.nochurn.sh/v1/api_keys/key_mmRMLWbYwsDkVuTW",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
    json={
      "name": "CI (read only)",
      "access": "restricted",
      "permissions": {
        "customers": "read"
      }
    },
)
api_key = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/api_keys/key_mmRMLWbYwsDkVuTW")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
  "name" => "CI (read only)",
  "access" => "restricted",
  "permissions" => {
    "customers" => "read"
  }
}.to_json

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
api_key = JSON.parse(res.body)
RESPONSE 200
{
  "object": "api_key",
  "id": "key_mmRMLWbYwsDkVuTW",
  "name": "CI (read only)",
  "kind": "secret",
  "mode": "test",
  "access": "restricted",
  "permissions": {
    "account": "none",
    "api_keys": "none",
    "team": "none",
    "events": "none",
    "customers": "read",
    "billing": "none",
    "stripe_connections": "none",
    "logs": "none",
    "flows": "none",
    "email_domains": "none",
    "messages": "none",
    "webhooks": "none",
    "cancel_sessions": "none",
    "reviews": "none",
    "dashboard": "none",
    "insights": "none",
    "integrations": "none",
    "queries": "none",
    "disputes": "none",
    "sandbox": "none"
  },
  "last4": "zNiY",
  "allowed_origins": null,
  "token": null,
  "first_used_at": null,
  "last_used_at": null,
  "revoked_at": null,
  "created_at": "2026-11-04T10:00:00.000Z"
}

Revoke an API key

  • Secret key (nc_test_… or nc_live_…). Restricted keys need write access.
  • AI apps (OAuth): not available.

PATH PARAMETERS

  • id string REQUIRED

RETURNS

ERRORS

DELETE/v1/api_keys/{id}
curl https://api.nochurn.sh/v1/api_keys/key_VYxpFgpYz8anfPXj \
  -X DELETE \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/api_keys/key_VYxpFgpYz8anfPXj", {
  method: "DELETE",
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const apiKey = await res.json();
import requests

res = requests.delete(
    "https://api.nochurn.sh/v1/api_keys/key_VYxpFgpYz8anfPXj",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
api_key = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/api_keys/key_VYxpFgpYz8anfPXj")
req = Net::HTTP::Delete.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
api_key = JSON.parse(res.body)
RESPONSE 200
{
  "object": "api_key",
  "id": "key_VYxpFgpYz8anfPXj",
  "name": "Key 1",
  "kind": "secret",
  "mode": "test",
  "access": "full",
  "permissions": {
    "account": "write",
    "api_keys": "write",
    "team": "write",
    "events": "write",
    "customers": "write",
    "billing": "write",
    "stripe_connections": "write",
    "logs": "write",
    "flows": "write",
    "email_domains": "write",
    "messages": "write",
    "webhooks": "write",
    "cancel_sessions": "write",
    "reviews": "write",
    "dashboard": "write",
    "insights": "write",
    "integrations": "write",
    "queries": "write",
    "disputes": "write",
    "sandbox": "write"
  },
  "last4": "oRgd",
  "allowed_origins": null,
  "token": null,
  "first_used_at": null,
  "last_used_at": null,
  "revoked_at": "2026-11-04T10:00:00.000Z",
  "created_at": "2026-11-04T10:00:00.000Z"
}

List the API keys of the current mode (live key or NoChurn-Mode header)

  • Secret key (nc_test_… or nc_live_…). Restricted keys need read access.
  • AI apps (OAuth): read scope.

QUERY PARAMETERS

  • limit integer default 20 · 1 to 100
  • Cursor: the next_cursor of the previous page.

RETURNS

ERRORS

GET/v1/api_keys
curl https://api.nochurn.sh/v1/api_keys \
  -H "Authorization: Bearer nc_test_…"
const res = await fetch("https://api.nochurn.sh/v1/api_keys", {
  headers: {
    Authorization: "Bearer nc_test_…",
  },
});
const page = await res.json();
import requests

res = requests.get(
    "https://api.nochurn.sh/v1/api_keys",
    headers={
        "Authorization": "Bearer nc_test_…",
    },
)
page = res.json()
require "net/http"
require "json"

uri = URI("https://api.nochurn.sh/v1/api_keys")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer nc_test_…"

res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
page = JSON.parse(res.body)
RESPONSE 200
{
  "object": "list",
  "data": [
    {
      "object": "api_key",
      "id": "key_KCvgEydsuK5U3G11",
      "name": "Key 1",
      "kind": "secret",
      "mode": "live",
      "access": "full",
      "permissions": {
        "account": "write",
        "api_keys": "write",
        "team": "write",
        "events": "write",
        "customers": "write",
        "billing": "write",
        "stripe_connections": "write",
        "logs": "write",
        "flows": "write",
        "email_domains": "write",
        "messages": "write",
        "webhooks": "write",
        "cancel_sessions": "write",
        "reviews": "write",
        "dashboard": "write",
        "insights": "write",
        "integrations": "write",
        "queries": "write",
        "disputes": "write",
        "sandbox": "write"
      },
      "last4": "G91q",
      "allowed_origins": null,
      "token": null,
      "first_used_at": null,
      "last_used_at": null,
      "revoked_at": null,
      "created_at": "2026-11-04T10:00:00.000Z"
    },
    {
      "object": "api_key",
      "id": "key_5MfRNbFWjVjA9Pwj",
      "name": "Key 4",
      "kind": "secret",
      "mode": "live",
      "access": "full",
      "permissions": {
        "account": "write",
        "api_keys": "write",
        "team": "write",
        "events": "write",
        "customers": "write",
        "billing": "write",
        "stripe_connections": "write",
        "logs": "write",
        "flows": "write",
        "email_domains": "write",
        "messages": "write",
        "webhooks": "write",
        "cancel_sessions": "write",
        "reviews": "write",
        "dashboard": "write",
        "insights": "write",
        "integrations": "write",
        "queries": "write",
        "disputes": "write",
        "sandbox": "write"
      },
      "last4": "hLa2",
      "allowed_origins": null,
      "token": null,
      "first_used_at": "2026-11-04T10:00:00.000Z",
      "last_used_at": "2026-11-04T10:00:00.000Z",
      "revoked_at": null,
      "created_at": "2026-11-04T10:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}