API reference
API: Calling compliance
| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | /v1/calling-compliance | The organization's calling and texting rules: window and states, opt-out scope, replies, disclosures, the DNC registry files, emergency blocks and the state rules table | settings:read |
| GET | /v1/calling-compliance/announcements | The call announcements, word for word: start (with the recording notice and opt-out), transfer, voicemail drop, recording on and off. Versioned with the disclosures; none can be removed. | settings:read |
| POST | /v1/calling-compliance/check | Would a text or call to this number be allowed now? Allow, deny or queue (with when), and every reason. Nothing is sent. | calls:read |
| GET | /v1/calling-compliance/consent-wording | The consent wording each channel shows when someone gives consent (forms, the SMS opt-in), with its version | settings:read |
| PUT | /v1/calling-compliance/consent-wording/:channel | Reword a channel's consent text (owners; versioned, checked: business name, opt-out, and for SMS help and rates, for calls automated or AI voice and not a condition of purchase) | settings:write |
| PUT | /v1/calling-compliance/disclosure | Reword the mandatory disclosures (owners). They can't be turned off: each must still name the business, say it's an AI and keep the opt-out. Saved as a new version; marked for counsel review. | settings:write |
| GET | /v1/calling-compliance/disclosure/preview | What's said or sent first: the voice opening lines, the SMS first-message line, or the email line and sender name | settings:read |
| POST | /v1/calling-compliance/emergencies | Block calls and texts to states or area codes for a state of emergency (owners; dates inclusive, contact-local) | settings:write |
| DELETE | /v1/calling-compliance/emergencies/:id | Lift a state-of-emergency block (owners) | settings:write |
| GET | /v1/calling-compliance/opt-out-reviews | Texts that may be opt-outs, waiting for an owner to decide (oldest first), each with its 10-business-day due date and whether it's overdue | calls:read |
| POST | /v1/calling-compliance/opt-out-reviews/:id | Decide a held text (owners, from the app; a reason is required and audited): an opt-out (applied under the organization's scope) or not one (the agent may answer again) (web app only) | settings:write |
| GET | /v1/calling-compliance/queue | The quiet-hours queue: texts and calls held by the calling window, a holiday, an emergency block or a state cap, with why and when each goes (numbers masked) | calls:read |
| POST | /v1/calling-compliance/queue/:id/cancel | Cancel a held text or call before it's released | calls:write |
| POST | /v1/calling-compliance/queue/:id/unmask | Show a held item's number in full (owners, from the app; audited) (web app only) | settings:write |
| PUT | /v1/calling-compliance/settings | Change the rules (owners). The window can be narrowed inside 08:00–20:00 contact-local, never widened; state rules always apply. | settings:write |
| GET | /v1/dnc | The organization's internal do-not-call list (numbers masked; an owner reveals one from the app, audited) | calls:read |
| POST | /v1/dnc | Add numbers to the internal do-not-call list (calls and texts stop at once; kept at least five years) | calls:write |
| DELETE | /v1/dnc/:id | Take a number off the internal do-not-call list (owners; audited). A number they asked to stop stays opted out in the ledger. | settings:write |
| POST | /v1/dnc/:id/unmask | Show a do-not-call entry's number in full (owners, from the app; audited) (web app only) | settings:write |
| GET | /v1/dnc/registry | Registry coverage per area code: last refresh, age and whether it's stale (over 31 days) | settings:read |
| POST | /v1/dnc/registry | Upload the organization's own National Do Not Call Registry download (CSV or text, one number per line; up to 20 MB per upload). Stored hashed per area code. mode=replace (default) clears and refills the area codes it covers; mode=merge adds the next part of the same download (within 24 hours). Refresh at least every 31 days, or marketing calls and texts to those area codes stop. | settings:write |
| POST | /v1/opt-outs | Record an opt-out someone asked for (by phone, in person, a spoken "don't call me"). Applied at once, under the organization's scope. | calls:write |
| POST | /v1/opt-outs/lift | Lift an opt-out block on one channel for a number (owners; audited). Texts or calls reopen without counting as their consent; email: the number's opt-out suppression is removed. Their objection stays in the ledger. | settings:write |
| GET | /v1/phone-ledger | A number's opt-out ledger (STOP, START, HELP, manual and spoken requests) and its consent entries, with the current status per channel | calls:read |
| POST | /v1/phones/:id/unmask | Show a do-not-call number in full (owners; audited) (web app only) | settings:write |
| POST | /v1/records/:id/unmask-phones | Show a record's do-not-call phone fields in full (owners; audited) (web app only) | settings:write |
Examples
GET /v1/calling-compliance
The organization's calling and texting rules: window and states, opt-out scope, replies, disclosures, the DNC registry files, emergency blocks and the state rules table
curl -s "https://api.closefinch.com/v1/calling-compliance" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/calling-compliance/announcements
The call announcements, word for word: start (with the recording notice and opt-out), transfer, voicemail drop, recording on and off. Versioned with the disclosures; none can be removed.
curl -s "https://api.closefinch.com/v1/calling-compliance/announcements" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/announcements`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/calling-compliance/check
Would a text or call to this number be allowed now? Allow, deny or queue (with when), and every reason. Nothing is sent.
curl -s -X POST "https://api.closefinch.com/v1/calling-compliance/check" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/check`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/calling-compliance/consent-wording
The consent wording each channel shows when someone gives consent (forms, the SMS opt-in), with its version
curl -s "https://api.closefinch.com/v1/calling-compliance/consent-wording" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/consent-wording`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/calling-compliance/consent-wording/$CHANNEL
Reword a channel's consent text (owners; versioned, checked: business name, opt-out, and for SMS help and rates, for calls automated or AI voice and not a condition of purchase)
curl -s -X PUT "https://api.closefinch.com/v1/calling-compliance/consent-wording/$CHANNEL" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/consent-wording/${channel}`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();PUT /v1/calling-compliance/disclosure
Reword the mandatory disclosures (owners). They can't be turned off: each must still name the business, say it's an AI and keep the opt-out. Saved as a new version; marked for counsel review.
curl -s -X PUT "https://api.closefinch.com/v1/calling-compliance/disclosure" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/disclosure`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/calling-compliance/disclosure/preview
What's said or sent first: the voice opening lines, the SMS first-message line, or the email line and sender name
curl -s "https://api.closefinch.com/v1/calling-compliance/disclosure/preview" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/disclosure/preview`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/calling-compliance/emergencies
Block calls and texts to states or area codes for a state of emergency (owners; dates inclusive, contact-local)
curl -s -X POST "https://api.closefinch.com/v1/calling-compliance/emergencies" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/emergencies`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();DELETE /v1/calling-compliance/emergencies/$ID
Lift a state-of-emergency block (owners)
curl -s -X DELETE "https://api.closefinch.com/v1/calling-compliance/emergencies/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/emergencies/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/calling-compliance/opt-out-reviews
Texts that may be opt-outs, waiting for an owner to decide (oldest first), each with its 10-business-day due date and whether it's overdue
curl -s "https://api.closefinch.com/v1/calling-compliance/opt-out-reviews" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/opt-out-reviews`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/calling-compliance/queue
The quiet-hours queue: texts and calls held by the calling window, a holiday, an emergency block or a state cap, with why and when each goes (numbers masked)
curl -s "https://api.closefinch.com/v1/calling-compliance/queue" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/queue`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/calling-compliance/queue/$ID/cancel
Cancel a held text or call before it's released
curl -s -X POST "https://api.closefinch.com/v1/calling-compliance/queue/$ID/cancel" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/queue/${id}/cancel`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();PUT /v1/calling-compliance/settings
Change the rules (owners). The window can be narrowed inside 08:00–20:00 contact-local, never widened; state rules always apply.
curl -s -X PUT "https://api.closefinch.com/v1/calling-compliance/settings" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/calling-compliance/settings`, {
method: "PUT",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/dnc
The organization's internal do-not-call list (numbers masked; an owner reveals one from the app, audited)
curl -s "https://api.closefinch.com/v1/dnc" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/dnc`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/dnc
Add numbers to the internal do-not-call list (calls and texts stop at once; kept at least five years)
curl -s -X POST "https://api.closefinch.com/v1/dnc" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/dnc`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();DELETE /v1/dnc/$ID
Take a number off the internal do-not-call list (owners; audited). A number they asked to stop stays opted out in the ledger.
curl -s -X DELETE "https://api.closefinch.com/v1/dnc/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/dnc/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/dnc/registry
Registry coverage per area code: last refresh, age and whether it's stale (over 31 days)
curl -s "https://api.closefinch.com/v1/dnc/registry" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/dnc/registry`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/dnc/registry
Upload the organization's own National Do Not Call Registry download (CSV or text, one number per line; up to 20 MB per upload). Stored hashed per area code. mode=replace (default) clears and refills the area codes it covers; mode=merge adds the next part of the same download (within 24 hours). Refresh at least every 31 days, or marketing calls and texts to those area codes stop.
curl -s -X POST "https://api.closefinch.com/v1/dnc/registry" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/dnc/registry`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/opt-outs
Record an opt-out someone asked for (by phone, in person, a spoken "don't call me"). Applied at once, under the organization's scope.
curl -s -X POST "https://api.closefinch.com/v1/opt-outs" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/opt-outs`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/opt-outs/lift
Lift an opt-out block on one channel for a number (owners; audited). Texts or calls reopen without counting as their consent; email: the number's opt-out suppression is removed. Their objection stays in the ledger.
curl -s -X POST "https://api.closefinch.com/v1/opt-outs/lift" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/opt-outs/lift`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();GET /v1/phone-ledger
A number's opt-out ledger (STOP, START, HELP, manual and spoken requests) and its consent entries, with the current status per channel
curl -s "https://api.closefinch.com/v1/phone-ledger" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/phone-ledger`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();Request and response schemas: https://www.closefinch.com/openapi.json. All resources: API reference.