# API: Phone and SMS

| Method | Path | What it does | Scope |
|---|---|---|---|
| DELETE | `/v1/me/sms-alerts` | Remove your mobile (no more SMS alerts) (web app only) | — |
| GET | `/v1/me/sms-alerts` | Your SMS alerts: your mobile (last digits), whether it's verified or stopped, quiet hours, and whether alerts quote the prospect's text | — |
| PATCH | `/v1/me/sms-alerts` | Your alert quiet hours (your time zone) and whether alerts quote the prospect's text (web app only) | — |
| POST | `/v1/me/sms-alerts/phone` | Add (or change) your own mobile for alerts: a code is texted to it from the organization's alert number (web app only) | — |
| POST | `/v1/me/sms-alerts/verify` | Confirm your mobile with the code you got (web app only) | — |
| POST | `/v1/sms/outreach` | Ask the agent to text a contact: the text waits in the approval inbox and goes only to someone with prior express written consent | `messages:send` |
| GET | `/v1/sms/threads` | Text threads, newest first (optionally one contact's) | `messages:read` |
| GET | `/v1/sms/threads/:id` | One text thread with its messages and their delivery status | `messages:read` |
| POST | `/v1/sms/threads/:id/claim` | Take the thread from the SMS agent (it stops answering until you hand it back) | `messages:write` |
| POST | `/v1/sms/threads/:id/messages` | Text from the thread as yourself (opt-outs, the texting window, consent and do-not-contact apply) (web app only) | `messages:send` |
| POST | `/v1/sms/threads/:id/release` | Hand the thread back to the SMS agent (it texts the contact again) | `messages:send` |
| GET | `/v1/telephony` | Phone and SMS: the Telnyx connection, whether its key and webhook key are set, the webhook URL, messaging profiles, numbers (and whether each may send yet), 10DLC/toll-free registrations and the SMS agent's settings | `settings:read` |
| PUT | `/v1/telephony` | Connect or change Telnyx (owner): the webhook's Ed25519 public key, on/off, and the SMS agent (off or auto, autonomy, confidence, the per-person daily cap, the hourly alert cap). The API key is the secret telnyx_api_key | `integrations:write` |
| POST | `/v1/telephony/numbers` | Add one of the organization's own Telnyx numbers (checked on its own Telnyx account; a number is active in one organization only), for prospect texting or staff alerts (owner) | `settings:write` |
| DELETE | `/v1/telephony/numbers/:id` | Stop using a number here (owner); it stays in the Telnyx account | `settings:write` |
| POST | `/v1/telephony/numbers/import` | Import the numbers Telnyx has on the organization's messaging profiles (owner) | `settings:write` |
| PUT | `/v1/telephony/profiles` | Set the Telnyx messaging profile for prospect texting or staff alerts (owner); the two must differ | `integrations:write` |
| GET | `/v1/telephony/registration-draft` | The 10DLC brand and campaign forms, filled from what the organization already told us, for an owner to review | `settings:write` |
| POST | `/v1/telephony/registrations` | Submit a 10DLC brand or campaign, or a toll-free verification, on the organization's Telnyx key (owner; metered: $4.50 a brand, $15 a campaign review) (web app only) | `settings:write` |
| POST | `/v1/telephony/registrations/refresh` | Check pending registrations with Telnyx now; an approved campaign takes in its purpose's numbers | `settings:write` |
| POST | `/v1/telephony/telnyx/webhook/:connection` | Telnyx messaging webhooks (public; Ed25519-signed over {telnyx-timestamp}\|{raw body}, 5-minute window; each event applied once) (no sign-in) | — |

## Examples

### GET /v1/me/sms-alerts

Your SMS alerts: your mobile (last digits), whether it's verified or stopped, quiet hours, and whether alerts quote the prospect's text

```bash
curl -s "https://api.closefinch.com/v1/me/sms-alerts" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/me/sms-alerts`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/sms/outreach

Ask the agent to text a contact: the text waits in the approval inbox and goes only to someone with prior express written consent

```bash
curl -s -X POST "https://api.closefinch.com/v1/sms/outreach" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/sms/outreach`, {
  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/sms/threads

Text threads, newest first (optionally one contact's)

```bash
curl -s "https://api.closefinch.com/v1/sms/threads" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/sms/threads`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/sms/threads/$ID

One text thread with its messages and their delivery status

```bash
curl -s "https://api.closefinch.com/v1/sms/threads/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/sms/threads/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/sms/threads/$ID/claim

Take the thread from the SMS agent (it stops answering until you hand it back)

```bash
curl -s -X POST "https://api.closefinch.com/v1/sms/threads/$ID/claim" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/sms/threads/${id}/claim`, {
  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/sms/threads/$ID/release

Hand the thread back to the SMS agent (it texts the contact again)

```bash
curl -s -X POST "https://api.closefinch.com/v1/sms/threads/$ID/release" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/sms/threads/${id}/release`, {
  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/telephony

Phone and SMS: the Telnyx connection, whether its key and webhook key are set, the webhook URL, messaging profiles, numbers (and whether each may send yet), 10DLC/toll-free registrations and the SMS agent's settings

```bash
curl -s "https://api.closefinch.com/v1/telephony" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PUT /v1/telephony

Connect or change Telnyx (owner): the webhook's Ed25519 public key, on/off, and the SMS agent (off or auto, autonomy, confidence, the per-person daily cap, the hourly alert cap). The API key is the secret telnyx_api_key

```bash
curl -s -X PUT "https://api.closefinch.com/v1/telephony" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony`, {
  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();
```

### POST /v1/telephony/numbers

Add one of the organization's own Telnyx numbers (checked on its own Telnyx account; a number is active in one organization only), for prospect texting or staff alerts (owner)

```bash
curl -s -X POST "https://api.closefinch.com/v1/telephony/numbers" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/numbers`, {
  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/telephony/numbers/$ID

Stop using a number here (owner); it stays in the Telnyx account

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/telephony/numbers/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/numbers/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/telephony/numbers/import

Import the numbers Telnyx has on the organization's messaging profiles (owner)

```bash
curl -s -X POST "https://api.closefinch.com/v1/telephony/numbers/import" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/numbers/import`, {
  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/telephony/profiles

Set the Telnyx messaging profile for prospect texting or staff alerts (owner); the two must differ

```bash
curl -s -X PUT "https://api.closefinch.com/v1/telephony/profiles" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/profiles`, {
  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/telephony/registration-draft

The 10DLC brand and campaign forms, filled from what the organization already told us, for an owner to review

```bash
curl -s "https://api.closefinch.com/v1/telephony/registration-draft" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/registration-draft`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/telephony/registrations/refresh

Check pending registrations with Telnyx now; an approved campaign takes in its purpose's numbers

```bash
curl -s -X POST "https://api.closefinch.com/v1/telephony/registrations/refresh" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
const res = await fetch(`https://api.closefinch.com/v1/telephony/registrations/refresh`, {
  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();
```

Request and response schemas: [https://www.closefinch.com/openapi.json](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
