DATA
Integrations
The Billing connection object
Billing tools, payment providers, app stores and help desks connected to NoChurn.
ATTRIBUTES
- object enum
- billing_connection
- id string
- provider enum
- stripe
- chargebee
- recurly
- maxio
- zuora
- paddle
- lemon_squeezy
- polar
- braintree
- mollie
- gocardless
- razorpay
- app_store
- google_play
- custom
- livemode boolean
- status enum
- active
- revoked
- error
- external_account_id string | null
- business_name string | null
- capabilities object
Show child attributesHide child attributes
- retries enum
- nochurn
- provider
- none
- card_update enum
- hosted_page
- provider_portal
- none
- offers array of enums
- coupon
- pause
- downgrade
- cancel_via_api boolean
- disputes enum
- evidence_api
- provider_handles
- refund_review
- none
- fraud_warnings boolean
- webhooks boolean
- backfill boolean
-
Show 10 more attributesHide 10 attributes
- available boolean
The provider's adapter is live on this NoChurn version.
- webhook_url string | null
Paste it in the provider's webhook settings (not for Stripe).
- backfill object
Show child attributesHide child attributes
- webhook_secret_set boolean
False until the provider's webhook secret is pasted (Recurly, Paddle, GoCardless, Razorpay): webhooks are refused until then. Always true for Stripe, for providers that sign webhooks with the API keys (Braintree) and for providers without a webhook secret (Mollie).
- settings object
What the account declares for this connection (stores only; {} otherwise).
Show child attributesHide child attributes
- refund_review object
Store refund reviews: NoChurn answers only if customer_consented is true (your app collects the consent); sample_content_provided is sent unless a free trial is seen on the purchase.
Show child attributesHide child attributes
- customer_consented boolean
- sample_content_provided boolean
-
- push_audience string
Google Play: the audience of the Pub/Sub push OIDC token. Set, pushes without a valid Google-signed token are refused.
- push_service_account_email string
Google Play: the service account that signs the push OIDC token.
-
- internal_id object | null
Where NoChurn reads your app's id for a customer (your user id, stored as external_id) in this tool; null for a tool that carries none (stores, universal webhook). Nothing found: the email decides.
Show child attributesHide child attributes
- error string | null
- webhook_setup object | null
Only in the response that creates the connection: webhook credentials to paste in the provider (e.g. Chargebee Basic auth). Shown once.
Schema: BillingConnection
{
"object": "billing_connection",
"id": "bcn_WLPj135TCf4cf9uS",
"provider": "chargebee",
"livemode": false,
"status": "active",
"external_account_id": "acme-test",
"business_name": "acme-test",
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": "https://api.nochurn.sh/webhooks/chargebee/-QEPYRNIzgjDa6SdZxc02GO3oW9oHifu",
"backfill": {
"status": "pending",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": true,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id", "cf_user_id"],
"fields": ["metadata.<name>", "cf_<name>", "id"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z",
"webhook_setup": {
"basic_auth_username": "nochurn",
"basic_auth_password": "EXAMPLE00000000000000000",
"api_version": "v2"
}
} Connect a provider with API keys
Providers arrive milestone by milestone: until then, provider_not_available.
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
BODY PARAMETERS
-
- stripe
- chargebee
- recurly
- maxio
- zuora
- paddle
- lemon_squeezy
- polar
- braintree
- mollie
- gocardless
- razorpay
- app_store
- google_play
- custom
- credentials object
The fields listed by GET /v1/billing_providers (e.g. site, api_key, region, webhook_secret; App Store: private_key, key_id, issuer_id, bundle_id; Google Play: service_account_json, package_name).
- settings object
Stores only: refund_review { customer_consented, sample_content_provided } (booleans); Google Play: push_audience, push_service_account_email ("" clears).
Show child parametersHide child parameters
- refund_review object
Show child parametersHide child parameters
- customer_consented boolean
- sample_content_provided boolean
-
- push_audience string
- push_service_account_email string
-
RETURNS
-
201connected (App Store sandbox): Apple keeps payment, retries and cancellation — the Billing connection object
ERRORS
-
400invalid_request unknown provider
curl https://api.nochurn.sh/v1/billing_connections \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{
"provider": "chargebee",
"credentials": {
"site": "acme-test",
"api_key": "test_x"
}
}'const res = await fetch("https://api.nochurn.sh/v1/billing_connections", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
"provider": "chargebee",
"credentials": {
"site": "acme-test",
"api_key": "test_x"
}
}),
});
const billingConnection = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/billing_connections",
headers={
"Authorization": "Bearer nc_test_…",
},
json={
"provider": "chargebee",
"credentials": {
"site": "acme-test",
"api_key": "test_x"
}
},
)
billing_connection = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
"provider" => "chargebee",
"credentials" => {
"site" => "acme-test",
"api_key" => "test_x"
}
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_connection = JSON.parse(res.body) {
"object": "billing_connection",
"id": "bcn_WLPj135TCf4cf9uS",
"provider": "chargebee",
"livemode": false,
"status": "active",
"external_account_id": "acme-test",
"business_name": "acme-test",
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": "https://api.nochurn.sh/webhooks/chargebee/-QEPYRNIzgjDa6SdZxc02GO3oW9oHifu",
"backfill": {
"status": "pending",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": true,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id", "cf_user_id"],
"fields": ["metadata.<name>", "cf_<name>", "id"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z",
"webhook_setup": {
"basic_auth_username": "nochurn",
"basic_auth_password": "EXAMPLE00000000000000000",
"api_version": "v2"
}
} A billing connection
- Secret key (
nc_test_…ornc_live_…). Restricted keys need read access. - AI apps (OAuth):
readscope.
PATH PARAMETERS
RETURNS
-
200the connection — the Billing connection object
curl https://api.nochurn.sh/v1/billing_connections/scn_4XXipZYv1tnXU99X \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_4XXipZYv1tnXU99X", {
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingConnection = await res.json();import requests
res = requests.get(
"https://api.nochurn.sh/v1/billing_connections/scn_4XXipZYv1tnXU99X",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_connection = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_4XXipZYv1tnXU99X")
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) }
billing_connection = JSON.parse(res.body) {
"object": "billing_connection",
"id": "scn_4XXipZYv1tnXU99X",
"provider": "stripe",
"livemode": false,
"status": "active",
"external_account_id": "acct_test1",
"business_name": null,
"capabilities": {
"retries": "nochurn",
"card_update": "hosted_page",
"offers": ["coupon", "pause", "downgrade"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": true,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": null,
"backfill": {
"status": "done",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": true,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id"],
"fields": ["metadata.<name>"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z"
} Change capabilities, the Stripe retry mode or where your user id is read
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
BODY PARAMETERS
- capabilities object
Only the keys sent change; locked ones are refused (GET /v1/billing_providers).
Show child parametersHide child parameters
- retries enum
- nochurn
- provider
- none
- card_update enum
- hosted_page
- provider_portal
- none
- offers array of enums
- coupon
- pause
- downgrade
- cancel_via_api boolean
-
- smart_retries_mode enum
- stripe
- nochurn
- internal_id_field string | null
Owner / admin. Where this tool keeps your app's id for a customer (a field or one key inside one, see internal_id.fields); null or "" = the tool's defaults. Applies to what NoChurn reads from now on.
- webhook_secret string
Write only: the secret of the webhook endpoint created on webhook_url (Recurly, Paddle, GoCardless, Razorpay).
- settings object
Stores only: refund_review { customer_consented, sample_content_provided } (booleans); Google Play: push_audience, push_service_account_email ("" clears).
Show child parametersHide child parameters
- refund_review object
Show child parametersHide child parameters
- customer_consented boolean
- sample_content_provided boolean
-
- push_audience string
- push_service_account_email string
-
RETURNS
-
200updated — the Billing connection object
curl https://api.nochurn.sh/v1/billing_connections/scn_qHHubuDxvBUkk4ZN \
-X PATCH \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{
"smart_retries_mode": "stripe"
}'const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_qHHubuDxvBUkk4ZN", {
method: "PATCH",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
"smart_retries_mode": "stripe"
}),
});
const billingConnection = await res.json();import requests
res = requests.patch(
"https://api.nochurn.sh/v1/billing_connections/scn_qHHubuDxvBUkk4ZN",
headers={
"Authorization": "Bearer nc_test_…",
},
json={
"smart_retries_mode": "stripe"
},
)
billing_connection = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_qHHubuDxvBUkk4ZN")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
"smart_retries_mode" => "stripe"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_connection = JSON.parse(res.body) {
"object": "billing_connection",
"id": "scn_qHHubuDxvBUkk4ZN",
"provider": "stripe",
"livemode": false,
"status": "active",
"external_account_id": "acct_test1",
"business_name": null,
"capabilities": {
"retries": "provider",
"card_update": "hosted_page",
"offers": ["coupon", "pause", "downgrade"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": true,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": null,
"backfill": {
"status": "done",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": true,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id"],
"fields": ["metadata.<name>"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z"
} Disconnect (credentials erased; synced data stays)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
200revoked — the Billing connection object
curl https://api.nochurn.sh/v1/billing_connections/bcn_G5sqaQTvcqqq3YGa \
-X DELETE \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/bcn_G5sqaQTvcqqq3YGa", {
method: "DELETE",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingConnection = await res.json();import requests
res = requests.delete(
"https://api.nochurn.sh/v1/billing_connections/bcn_G5sqaQTvcqqq3YGa",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_connection = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/bcn_G5sqaQTvcqqq3YGa")
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) }
billing_connection = JSON.parse(res.body) {
"object": "billing_connection",
"id": "bcn_G5sqaQTvcqqq3YGa",
"provider": "chargebee",
"livemode": false,
"status": "revoked",
"external_account_id": "acme-test",
"business_name": null,
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": null,
"backfill": {
"status": "done",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": false,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id", "cf_user_id"],
"fields": ["metadata.<name>", "cf_<name>", "id"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z"
} Connected billing providers
Every provider with its capability matrix (what NoChurn can do with it). Stripe keeps /v1/stripe_connections.
- Secret key (
nc_test_…ornc_live_…). Restricted keys need read access. - AI apps (OAuth):
readscope.
RETURNS
-
200with capabilities — a list of Billing connection object (BillingConnectionList)
curl https://api.nochurn.sh/v1/billing_connections \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections", {
headers: {
Authorization: "Bearer nc_test_…",
},
});
const page = await res.json();import requests
res = requests.get(
"https://api.nochurn.sh/v1/billing_connections",
headers={
"Authorization": "Bearer nc_test_…",
},
)
page = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections")
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) {
"object": "list",
"data": [
{
"object": "billing_connection",
"id": "scn_LVV5Gkx9djjhXDGN",
"provider": "stripe",
"livemode": false,
"status": "active",
"external_account_id": "acct_test1",
"business_name": null,
"capabilities": {
"retries": "nochurn",
"card_update": "hosted_page",
"offers": ["coupon", "pause", "downgrade"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": true,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": null,
"backfill": {
"status": "done",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": true,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id"],
"fields": ["metadata.<name>"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z"
}
],
"has_more": false,
"next_cursor": null
} Import again (12 months)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
202queued — the Billing connection object
curl https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/backfill \
-X POST \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/backfill", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingConnection = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/backfill",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_connection = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/backfill")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_connection = JSON.parse(res.body) {
"object": "billing_connection",
"id": "bcn_bd2nxUWHSGoShYqJ",
"provider": "chargebee",
"livemode": false,
"status": "active",
"external_account_id": "acme-test",
"business_name": null,
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"available": true,
"webhook_url": "https://api.nochurn.sh/webhooks/chargebee/tok_cb2",
"backfill": {
"status": "pending",
"progress": {},
"started_at": null,
"finished_at": null,
"error": null
},
"webhook_secret_set": false,
"settings": {},
"internal_id": {
"field": null,
"defaults": ["metadata.user_id", "cf_user_id"],
"fields": ["metadata.<name>", "cf_<name>", "id"]
},
"last_event_at": null,
"error": null,
"created_at": "2026-11-04T10:00:00Z"
} Billing providers (supported and coming)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need read access. - AI apps (OAuth):
readscope.
RETURNS
-
200every provider, available or not — a list of BillingProvider (BillingProviderList)
curl https://api.nochurn.sh/v1/billing_providers \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_providers", {
headers: {
Authorization: "Bearer nc_test_…",
},
});
const page = await res.json();import requests
res = requests.get(
"https://api.nochurn.sh/v1/billing_providers",
headers={
"Authorization": "Bearer nc_test_…",
},
)
page = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_providers")
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) {
"object": "list",
"data": [
{
"object": "billing_provider",
"provider": "stripe",
"family": "billing",
"available": true,
"connect": "oauth",
"credentials": [],
"capabilities": {
"retries": "provider",
"card_update": "hosted_page",
"offers": ["coupon", "pause", "downgrade"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": true,
"webhooks": true,
"backfill": true
},
"locked": [],
"webhook_secret": "none",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/stripe/"
},
{
"object": "billing_provider",
"provider": "chargebee",
"family": "billing",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "site",
"secret": false,
"hint": "The part before .chargebee.com (test site: <name>-test)"
},
{
"name": "api_key",
"secret": true,
"hint": "Settings › Configure Chargebee › API keys (full access)"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": [],
"webhook_secret": "generated",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/chargebee/"
},
{
"object": "billing_provider",
"provider": "recurly",
"family": "billing",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "api_key",
"secret": true,
"hint": "Integrations › API credentials (private key)"
},
{
"name": "region",
"secret": false,
"hint": "us or eu",
"options": ["us", "eu"]
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": [],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/recurly/"
},
{
"object": "billing_provider",
"provider": "maxio",
"family": "billing",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "subdomain",
"secret": false,
"hint": "The part before .chargify.com, or the full address of an EU site (acme.ebilling.maxio.com). A site in test mode in Test mode"
},
{
"name": "api_key",
"secret": true,
"hint": "Config › Integrations › API keys"
},
{
"name": "site_shared_key",
"secret": true,
"hint": "Config › Settings › Site shared key: signs the webhooks"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": [],
"webhook_secret": "none",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/maxio/"
},
{
"object": "billing_provider",
"provider": "zuora",
"family": "billing",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "environment",
"secret": false,
"hint": "Where your tenant lives (sandbox or test in Test mode)",
"options": [
"sandbox",
"test",
"na_sandbox",
"eu_sandbox",
"eu_test",
"ap_test",
"production",
"na_production",
"eu_production",
"ap_production"
]
},
{
"name": "client_id",
"secret": false,
"hint": "Settings › Administration › Manage users › OAuth client (API user with read and subscription rights)"
},
{
"name": "client_secret",
"secret": true,
"hint": "Shown once when the OAuth client is created"
}
],
"capabilities": {
"retries": "provider",
"card_update": "none",
"offers": ["pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": false,
"backfill": true
},
"locked": ["card_update"],
"webhook_secret": "none",
"hint": "NoChurn reads your Zuora tenant every 10 minutes (accounts, subscriptions, invoices, payments): no callout to configure. Retries and the payment page stay with Zuora.",
"docs_url": "https://nochurn.sh/docs/integrations/zuora/"
},
{
"object": "billing_provider",
"provider": "paddle",
"family": "merchant_of_record",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "api_key",
"secret": true,
"hint": "Developer tools › Authentication (sandbox key in Test mode), with the Customer portal session permission (card update links)"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "disputes"],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/paddle/"
},
{
"object": "billing_provider",
"provider": "lemon_squeezy",
"family": "merchant_of_record",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "api_key",
"secret": true,
"hint": "Settings › API (a test mode key in Test mode)"
},
{
"name": "store_id",
"secret": false,
"hint": "Settings › Stores: the store's number"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "disputes"],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/lemon-squeezy/"
},
{
"object": "billing_provider",
"provider": "polar",
"family": "merchant_of_record",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "access_token",
"secret": true,
"hint": "Settings › Developers › Organization access token (a sandbox.polar.sh token in Test mode)"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["coupon", "pause"],
"cancel_via_api": true,
"disputes": "provider_handles",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "disputes"],
"webhook_secret": "pasted",
"hint": "Create a webhook endpoint in Polar › Settings › Webhooks with webhook_url, format Raw and API version 2026-10 (the version NoChurn reads), then paste its secret (whsec_…) here.",
"docs_url": "https://nochurn.sh/docs/integrations/polar/"
},
{
"object": "billing_provider",
"provider": "braintree",
"family": "payments",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "merchant_id",
"secret": false,
"hint": "Settings › Business (sandbox account in Test mode)"
},
{
"name": "public_key",
"secret": false,
"hint": "Settings › API › API keys"
},
{
"name": "private_key",
"secret": true,
"hint": "Settings › API › API keys (View)"
}
],
"capabilities": {
"retries": "provider",
"card_update": "none",
"offers": ["coupon"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["card_update"],
"webhook_secret": "none",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/braintree/"
},
{
"object": "billing_provider",
"provider": "mollie",
"family": "payments",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "api_key",
"secret": true,
"hint": "Developers › API keys (test_… in Test mode, live_… in Live mode)"
}
],
"capabilities": {
"retries": "nochurn",
"card_update": "hosted_page",
"offers": [],
"cancel_via_api": true,
"disputes": "none",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["disputes"],
"webhook_secret": "none",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/mollie/"
},
{
"object": "billing_provider",
"provider": "gocardless",
"family": "payments",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "access_token",
"secret": true,
"hint": "Developers › Create › Access token, read-write (sandbox token in Test mode)"
}
],
"capabilities": {
"retries": "nochurn",
"card_update": "hosted_page",
"offers": ["pause"],
"cancel_via_api": true,
"disputes": "none",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["disputes"],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/gocardless/"
},
{
"object": "billing_provider",
"provider": "razorpay",
"family": "payments",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "key_id",
"secret": false,
"hint": "Account & Settings › API keys (rzp_test_… in Test mode)"
},
{
"name": "key_secret",
"secret": true,
"hint": "Shown once when the key is generated"
}
],
"capabilities": {
"retries": "provider",
"card_update": "provider_portal",
"offers": ["pause"],
"cancel_via_api": true,
"disputes": "evidence_api",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "offers"],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/razorpay/"
},
{
"object": "billing_provider",
"provider": "app_store",
"family": "stores",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "private_key",
"secret": true,
"hint": "The .p8 file of an In-App Purchase key (App Store Connect › Users and Access › Integrations › In-App Purchase), pasted whole"
},
{
"name": "key_id",
"secret": false,
"hint": "The key's ID, next to it in App Store Connect"
},
{
"name": "issuer_id",
"secret": false,
"hint": "Issuer ID, at the top of the same page"
},
{
"name": "bundle_id",
"secret": false,
"hint": "Your app's bundle ID (e.g. com.acme.app)"
}
],
"capabilities": {
"retries": "none",
"card_update": "none",
"offers": [],
"cancel_via_api": false,
"disputes": "refund_review",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "card_update", "disputes"],
"webhook_secret": "none",
"hint": "Apple shares no email: customers are linked only when your app sets an appAccountToken at purchase and sends it to NoChurn (as the external_id, or the app_account_token attribute of the customer). Without it, events stay unlinked. Paste webhook_url as the App Store Server Notifications V2 URL (sandbox URL in Test mode).",
"docs_url": "https://nochurn.sh/docs/integrations/app-store/"
},
{
"object": "billing_provider",
"provider": "google_play",
"family": "stores",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "service_account_json",
"secret": true,
"hint": "JSON key of a Google Cloud service account invited in Play Console › Users and permissions (view financial data, manage orders and subscriptions)"
},
{
"name": "package_name",
"secret": false,
"hint": "Your app's package name (e.g. com.acme.app)"
}
],
"capabilities": {
"retries": "none",
"card_update": "none",
"offers": [],
"cancel_via_api": true,
"disputes": "refund_review",
"fraud_warnings": false,
"webhooks": true,
"backfill": true
},
"locked": ["retries", "card_update", "disputes"],
"webhook_secret": "none",
"hint": "Customers are linked only when your app sets obfuscatedAccountId at purchase and sends it to NoChurn (as the external_id, or the obfuscated_account_id attribute of the customer). Without it, events stay unlinked. Create a Pub/Sub push subscription to webhook_url on the topic of your real-time developer notifications. Test mode applies license testers' purchases only.",
"docs_url": "https://nochurn.sh/docs/integrations/google-play/"
},
{
"object": "billing_provider",
"provider": "custom",
"family": "custom",
"available": true,
"connect": "credentials",
"credentials": [
{
"name": "name",
"secret": false,
"hint": "The name of your billing system, as shown in NoChurn"
},
{
"name": "signature_mode",
"secret": false,
"hint": "How your billing system signs its webhooks",
"options": ["hmac_sha256", "header_secret"]
},
{
"name": "signature_header",
"secret": false,
"hint": "The header carrying the signature or the secret (e.g. X-Signature)"
},
{
"name": "signature_encoding",
"secret": false,
"hint": "HMAC only: how the signature is written",
"options": ["hex", "base64"]
}
],
"capabilities": {
"retries": "none",
"card_update": "none",
"offers": [],
"cancel_via_api": false,
"disputes": "none",
"fraud_warnings": false,
"webhooks": true,
"backfill": false
},
"locked": [
"retries",
"card_update",
"offers",
"cancel_via_api",
"disputes",
"fraud_warnings",
"webhooks",
"backfill"
],
"webhook_secret": "pasted",
"hint": null,
"docs_url": "https://nochurn.sh/docs/integrations/custom/"
}
],
"has_more": false,
"next_cursor": null
} Mapping of a custom billing connection, tested on its sample
- Secret key (
nc_test_…ornc_live_…). Restricted keys need read access. - AI apps (OAuth):
readscope.
PATH PARAMETERS
RETURNS
-
200rules, state and the last webhooks with their result — a BillingMapping
curl https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping", {
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingMapping = await res.json();import requests
res = requests.get(
"https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_mapping = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping")
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) }
billing_mapping = JSON.parse(res.body) {
"object": "billing_mapping",
"billing_connection": "bcn_pEFhqdfNzf8kNZu4",
"active": false,
"activated_at": null,
"rules": [],
"types": [
"customer.upserted",
"subscription.created",
"subscription.updated",
"subscription.paused",
"subscription.resumed",
"subscription.canceled",
"subscription.renewed",
"invoice.paid",
"invoice.payment_failed",
"invoice.uncollectible",
"invoice.updated"
],
"fields": {
"customer": ["id", "email", "name", "country", "locale", "external_id"],
"subscription": [
"id",
"status",
"plan",
"amount_cents",
"currency",
"interval",
"interval_count",
"current_period_end",
"cancel_at_period_end",
"started_at",
"canceled_at",
"ended_at"
],
"invoice": [
"id",
"subscription_id",
"status",
"amount_due_cents",
"amount_paid_cents",
"amount_remaining_cents",
"currency",
"attempt_count",
"decline_code",
"failure_code",
"next_attempt_at",
"hosted_invoice_url"
]
},
"transforms": [
"units_to_cents",
"unix_seconds",
"unix_millis",
"lowercase",
"boolean",
"string"
],
"sample": [
{
"id": "bws_UdGw7Rgf3vMuJkXV",
"received_at": "2026-11-04T10:00:00Z",
"payload": {
"id": "wh_1",
"data": {
"email": "ana@example.test",
"amount": "49.90",
"invoice": "inv_wh_1",
"currency": "eur",
"customer": "c_1"
},
"type": "invoice.failed"
},
"result": {
"status": "ignored",
"rule": null,
"type": null,
"event_id": null,
"data": null,
"errors": []
}
}
],
"summary": {
"total": 1,
"events": 0,
"errors": 0,
"ignored": 1
}
} Save the mapping rules (tested on the sample)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
BODY PARAMETERS
RETURNS
-
200saved; each sample webhook with what it becomes — a BillingMapping
ERRORS
-
400invalid_request invalid rules
curl https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping \
-X PUT \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{
"rules": [
{
"when": {
"path": "$.type",
"equals": "invoice.failed"
},
"type": "invoice.payment_failed",
"event_id": "$.id",
"fields": {
"customer.id": "$.data.customer",
"customer.email": "$.data.email",
"invoice.id": "$.data.invoice",
"invoice.amount_due_cents": {
"path": "$.data.amount",
"transform": "units_to_cents"
},
"invoice.currency": "$.data.currency"
}
}
]
}'const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping", {
method: "PUT",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
"rules": [
{
"when": {
"path": "$.type",
"equals": "invoice.failed"
},
"type": "invoice.payment_failed",
"event_id": "$.id",
"fields": {
"customer.id": "$.data.customer",
"customer.email": "$.data.email",
"invoice.id": "$.data.invoice",
"invoice.amount_due_cents": {
"path": "$.data.amount",
"transform": "units_to_cents"
},
"invoice.currency": "$.data.currency"
}
}
]
}),
});
const billingMapping = await res.json();import requests
res = requests.put(
"https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping",
headers={
"Authorization": "Bearer nc_test_…",
},
json={
"rules": [
{
"when": {
"path": "$.type",
"equals": "invoice.failed"
},
"type": "invoice.payment_failed",
"event_id": "$.id",
"fields": {
"customer.id": "$.data.customer",
"customer.email": "$.data.email",
"invoice.id": "$.data.invoice",
"invoice.amount_due_cents": {
"path": "$.data.amount",
"transform": "units_to_cents"
},
"invoice.currency": "$.data.currency"
}
}
]
},
)
billing_mapping = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping")
req = Net::HTTP::Put.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
"rules" => [
{
"when" => {
"path" => "$.type",
"equals" => "invoice.failed"
},
"type" => "invoice.payment_failed",
"event_id" => "$.id",
"fields" => {
"customer.id" => "$.data.customer",
"customer.email" => "$.data.email",
"invoice.id" => "$.data.invoice",
"invoice.amount_due_cents" => {
"path" => "$.data.amount",
"transform" => "units_to_cents"
},
"invoice.currency" => "$.data.currency"
}
}
]
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_mapping = JSON.parse(res.body) {
"object": "billing_mapping",
"billing_connection": "bcn_mVxfYN2KgqTevEbE",
"active": false,
"activated_at": null,
"rules": [
{
"when": {
"path": "$.type",
"equals": "invoice.failed"
},
"type": "invoice.payment_failed",
"event_id": "$.id",
"fields": {
"customer.id": "$.data.customer",
"customer.email": "$.data.email",
"invoice.id": "$.data.invoice",
"invoice.amount_due_cents": {
"path": "$.data.amount",
"transform": "units_to_cents"
},
"invoice.currency": "$.data.currency"
}
}
],
"types": [
"customer.upserted",
"subscription.created",
"subscription.updated",
"subscription.paused",
"subscription.resumed",
"subscription.canceled",
"subscription.renewed",
"invoice.paid",
"invoice.payment_failed",
"invoice.uncollectible",
"invoice.updated"
],
"fields": {
"customer": ["id", "email", "name", "country", "locale", "external_id"],
"subscription": [
"id",
"status",
"plan",
"amount_cents",
"currency",
"interval",
"interval_count",
"current_period_end",
"cancel_at_period_end",
"started_at",
"canceled_at",
"ended_at"
],
"invoice": [
"id",
"subscription_id",
"status",
"amount_due_cents",
"amount_paid_cents",
"amount_remaining_cents",
"currency",
"attempt_count",
"decline_code",
"failure_code",
"next_attempt_at",
"hosted_invoice_url"
]
},
"transforms": [
"units_to_cents",
"unix_seconds",
"unix_millis",
"lowercase",
"boolean",
"string"
],
"sample": [
{
"id": "bws_rcEbEUxNJYg4jyS4",
"received_at": "2026-11-04T10:00:00Z",
"payload": {
"id": "wh_1",
"data": {
"email": "ana@example.test",
"amount": "49.90",
"invoice": "inv_wh_1",
"currency": "eur",
"customer": "c_1"
},
"type": "invoice.failed"
},
"result": {
"status": "event",
"rule": 0,
"type": "invoice.payment_failed",
"event_id": "wh_1",
"data": {
"invoice": {
"currency": "eur",
"id": "inv_wh_1",
"amount_due_cents": 4990
},
"customer": {
"id": "c_1",
"email": "ana@example.test"
}
},
"errors": []
}
}
],
"summary": {
"total": 1,
"events": 1,
"errors": 0,
"ignored": 0
}
} Turn the mapping on (the sample must pass)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
200on — a BillingMapping
ERRORS
-
409conflict the sample does not pass yet
curl https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/activate \
-X POST \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/activate", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingMapping = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/activate",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_mapping = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/activate")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_mapping = JSON.parse(res.body) {
"object": "billing_mapping",
"billing_connection": "bcn_7ihcvkgpzms1J5ee",
"active": true,
"activated_at": "2026-11-04T10:00:00Z",
"rules": [
{
"type": "invoice.payment_failed",
"when": {
"path": "$.type",
"equals": "invoice.failed"
},
"fields": {
"invoice.id": "$.data.invoice",
"customer.id": "$.data.customer",
"customer.email": "$.data.email",
"invoice.currency": "$.data.currency",
"invoice.amount_due_cents": {
"path": "$.data.amount",
"transform": "units_to_cents"
}
},
"event_id": "$.id"
}
],
"types": [
"customer.upserted",
"subscription.created",
"subscription.updated",
"subscription.paused",
"subscription.resumed",
"subscription.canceled",
"subscription.renewed",
"invoice.paid",
"invoice.payment_failed",
"invoice.uncollectible",
"invoice.updated"
],
"fields": {
"customer": ["id", "email", "name", "country", "locale", "external_id"],
"subscription": [
"id",
"status",
"plan",
"amount_cents",
"currency",
"interval",
"interval_count",
"current_period_end",
"cancel_at_period_end",
"started_at",
"canceled_at",
"ended_at"
],
"invoice": [
"id",
"subscription_id",
"status",
"amount_due_cents",
"amount_paid_cents",
"amount_remaining_cents",
"currency",
"attempt_count",
"decline_code",
"failure_code",
"next_attempt_at",
"hosted_invoice_url"
]
},
"transforms": [
"units_to_cents",
"unix_seconds",
"unix_millis",
"lowercase",
"boolean",
"string"
],
"sample": [
{
"id": "bws_VCjNWusA1bhGbbGR",
"received_at": "2026-11-04T10:00:00Z",
"payload": {
"id": "wh_1",
"data": {
"email": "ana@example.test",
"amount": "49.90",
"invoice": "inv_wh_1",
"currency": "eur",
"customer": "c_1"
},
"type": "invoice.failed"
},
"result": {
"status": "event",
"rule": 0,
"type": "invoice.payment_failed",
"event_id": "wh_1",
"data": {
"invoice": {
"currency": "eur",
"id": "inv_wh_1",
"amount_due_cents": 4990
},
"customer": {
"id": "c_1",
"email": "ana@example.test"
}
},
"errors": []
}
}
],
"summary": {
"total": 1,
"events": 1,
"errors": 0,
"ignored": 0
}
} Turn the mapping off (webhooks are only kept as a sample)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
200off — a BillingMapping
curl https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/deactivate \
-X POST \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/deactivate", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const billingMapping = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/deactivate",
headers={
"Authorization": "Bearer nc_test_…",
},
)
billing_mapping = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/billing_connections/scn_LVV5Gkx9djjhXDGN/mapping/deactivate")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
billing_mapping = JSON.parse(res.body) {
"object": "billing_mapping",
"billing_connection": "bcn_omV4hFm5EZYzNGTC",
"active": false,
"activated_at": null,
"rules": [],
"types": [
"customer.upserted",
"subscription.created",
"subscription.updated",
"subscription.paused",
"subscription.resumed",
"subscription.canceled",
"subscription.renewed",
"invoice.paid",
"invoice.payment_failed",
"invoice.uncollectible",
"invoice.updated"
],
"fields": {
"customer": ["id", "email", "name", "country", "locale", "external_id"],
"subscription": [
"id",
"status",
"plan",
"amount_cents",
"currency",
"interval",
"interval_count",
"current_period_end",
"cancel_at_period_end",
"started_at",
"canceled_at",
"ended_at"
],
"invoice": [
"id",
"subscription_id",
"status",
"amount_due_cents",
"amount_paid_cents",
"amount_remaining_cents",
"currency",
"attempt_count",
"decline_code",
"failure_code",
"next_attempt_at",
"hosted_invoice_url"
]
},
"transforms": [
"units_to_cents",
"unix_seconds",
"unix_millis",
"lowercase",
"boolean",
"string"
],
"sample": [],
"summary": {
"total": 0,
"events": 0,
"errors": 0,
"ignored": 0
}
} Connected tools
- Secret key (
nc_test_…ornc_live_…). Restricted keys need read access. - AI apps (OAuth):
readscope.
RETURNS
-
200credentials are never returned — a list of Integration (IntegrationList)
curl https://api.nochurn.sh/v1/integrations \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/integrations", {
headers: {
Authorization: "Bearer nc_test_…",
},
});
const page = await res.json();import requests
res = requests.get(
"https://api.nochurn.sh/v1/integrations",
headers={
"Authorization": "Bearer nc_test_…",
},
)
page = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations")
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) {
"object": "list",
"has_more": false,
"next_cursor": null,
"data": [
{
"object": "integration",
"id": "itg_GryteF3meCbHffEf",
"kind": "slack",
"status": "active",
"external_account": "Acme",
"config": {},
"last_synced_at": null,
"error": null,
"conversations_count": null,
"created_at": "2026-11-04T10:00:00Z"
}
]
} Connect Crisp (website or plugin token) or Gorgias (REST API key)
Crisp: identifier, key (a website token from Settings › Workspace Settings › Advanced configuration › API Token, or a Marketplace plugin token), website_id. Gorgias: domain (the part before .gorgias.com), email and api_key (Settings › Account › REST API). Read only; credentials are encrypted and never returned.
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
BODY PARAMETERS
One of:
-
- crisp
RETURNS
-
201connected (read only) — a Integration
ERRORS
-
400invalid_request Crisp refused the credentials or does not know the website
curl https://api.nochurn.sh/v1/integrations \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{
"kind": "crisp",
"identifier": "id_test",
"key": "key_test",
"website_id": "8c1f3f52-2a8a-4d6b-9a0e-6f1f2c3d4e5f"
}'const res = await fetch("https://api.nochurn.sh/v1/integrations", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
"kind": "crisp",
"identifier": "id_test",
"key": "key_test",
"website_id": "8c1f3f52-2a8a-4d6b-9a0e-6f1f2c3d4e5f"
}),
});
const integration = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/integrations",
headers={
"Authorization": "Bearer nc_test_…",
},
json={
"kind": "crisp",
"identifier": "id_test",
"key": "key_test",
"website_id": "8c1f3f52-2a8a-4d6b-9a0e-6f1f2c3d4e5f"
},
)
integration = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
"kind" => "crisp",
"identifier" => "id_test",
"key" => "key_test",
"website_id" => "8c1f3f52-2a8a-4d6b-9a0e-6f1f2c3d4e5f"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
integration = JSON.parse(res.body) {
"object": "integration",
"id": "itg_PTnp2N7f2MPagEv6",
"kind": "crisp",
"status": "active",
"external_account": "Acme",
"config": {},
"last_synced_at": null,
"error": null,
"conversations_count": 0,
"created_at": "2026-11-04T10:00:00Z"
} OAuth URL of a support tool or Slack
The dashboard only redirects to url. Zendesk needs the account's subdomain (connect as a Zendesk admin). Intercom takes an optional region (us, eu, au: where the workspace is hosted; us by default) for its authorization host.
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
-
- intercom
- zendesk
- hubspot
- helpscout
- slack
BODY PARAMETERS
RETURNS
-
200the URL — a IntegrationAuthorizeUrl
ERRORS
-
400invalid_request unknown region
curl https://api.nochurn.sh/v1/integrations/intercom/authorize \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{}'const res = await fetch("https://api.nochurn.sh/v1/integrations/intercom/authorize", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({}),
});
const authorizeUrl = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/integrations/intercom/authorize",
headers={
"Authorization": "Bearer nc_test_…",
},
json={},
)
authorize_url = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations/intercom/authorize")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
authorize_url = JSON.parse(res.body) {
"object": "authorize_url",
"kind": "intercom",
"url": "https://app.intercom.com/oauth?client_id=ic_test&state=eyJfcmFpbHMiOnsiZGF0YSI6eyJhY2NvdW50X2lkIjoiYWNjX3F2YXRjSlR6d25DWjRaWUoiLCJ1c2VyX2lkIjpudWxsLCJraW5kIjoiaW50ZXJjb20iLCJub25jZSI6IjE2OWU1ZDQ5MTcxNGZjYmQifSwiZXhwIjoiMjAyNi0xMS0wNFQxMDozMDowMC4wMDBaIiwicHVyIjoiaW50ZWdyYXRpb24ifX0%3D--7d97ba0133a2d258517598968809f921d24c10e0"
} Slack channel
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
BODY PARAMETERS
RETURNS
-
200updated — a Integration
curl https://api.nochurn.sh/v1/integrations/itg_WFTBKq2vf2R8QZMo \
-X PATCH \
-H "Authorization: Bearer nc_test_…" \
-H "Content-Type: application/json" \
-d '{
"config": {
"channel": "#retention"
}
}'const res = await fetch("https://api.nochurn.sh/v1/integrations/itg_WFTBKq2vf2R8QZMo", {
method: "PATCH",
headers: {
Authorization: "Bearer nc_test_…",
"Content-Type": "application/json",
},
body: JSON.stringify({
"config": {
"channel": "#retention"
}
}),
});
const integration = await res.json();import requests
res = requests.patch(
"https://api.nochurn.sh/v1/integrations/itg_WFTBKq2vf2R8QZMo",
headers={
"Authorization": "Bearer nc_test_…",
},
json={
"config": {
"channel": "#retention"
}
},
)
integration = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations/itg_WFTBKq2vf2R8QZMo")
req = Net::HTTP::Patch.new(uri)
req["Authorization"] = "Bearer nc_test_…"
req["Content-Type"] = "application/json"
req.body = {
"config" => {
"channel" => "#retention"
}
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
integration = JSON.parse(res.body) {
"object": "integration",
"id": "itg_WFTBKq2vf2R8QZMo",
"kind": "slack",
"status": "active",
"external_account": "Acme",
"config": {
"channel": "#retention"
},
"last_synced_at": null,
"error": null,
"conversations_count": null,
"created_at": "2026-11-04T10:00:00Z"
} Disconnect
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
200credentials erased — a Integration
curl https://api.nochurn.sh/v1/integrations/itg_tRyqFBV8V6BgHf6d \
-X DELETE \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/integrations/itg_tRyqFBV8V6BgHf6d", {
method: "DELETE",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const integration = await res.json();import requests
res = requests.delete(
"https://api.nochurn.sh/v1/integrations/itg_tRyqFBV8V6BgHf6d",
headers={
"Authorization": "Bearer nc_test_…",
},
)
integration = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations/itg_tRyqFBV8V6BgHf6d")
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) }
integration = JSON.parse(res.body) {
"object": "integration",
"id": "itg_tRyqFBV8V6BgHf6d",
"kind": "slack",
"status": "revoked",
"external_account": "Acme",
"config": {},
"last_synced_at": null,
"error": null,
"conversations_count": null,
"created_at": "2026-11-04T10:00:00Z"
} Sync now (support tools)
- Secret key (
nc_test_…ornc_live_…). Restricted keys need write access. - AI apps (OAuth): not available.
PATH PARAMETERS
RETURNS
-
202queued — a Integration
ERRORS
-
409conflict not connected
curl https://api.nochurn.sh/v1/integrations/itg_GryteF3meCbHffEf/sync \
-X POST \
-H "Authorization: Bearer nc_test_…"const res = await fetch("https://api.nochurn.sh/v1/integrations/itg_GryteF3meCbHffEf/sync", {
method: "POST",
headers: {
Authorization: "Bearer nc_test_…",
},
});
const integration = await res.json();import requests
res = requests.post(
"https://api.nochurn.sh/v1/integrations/itg_GryteF3meCbHffEf/sync",
headers={
"Authorization": "Bearer nc_test_…",
},
)
integration = res.json()require "net/http"
require "json"
uri = URI("https://api.nochurn.sh/v1/integrations/itg_GryteF3meCbHffEf/sync")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer nc_test_…"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
integration = JSON.parse(res.body) {
"object": "integration",
"id": "itg_Pa34cY9hMexK8b2u",
"kind": "intercom",
"status": "active",
"external_account": "Acme",
"config": {},
"last_synced_at": null,
"error": null,
"conversations_count": 0,
"created_at": "2026-11-04T10:00:00Z"
}