# API: Vendors

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/ad-audiences` | Ad audiences synced from segments, with status and match rate per destination | `sequences:read` |
| POST | `/v1/ad-audiences` | Create an ad audience from a segment (a list of contacts); nothing is uploaded until an organization owner approves (web app only) | `sequences:write` |
| POST | `/v1/ad-audiences/:id/approve` | Approve the first upload (hashed emails) to the ad platform (an organization owner, signed in) (web app only) | `sequences:write` |
| POST | `/v1/ad-audiences/:id/archive` | Archive an audience: everyone in it is removed at the platform first (an organization owner, signed in) (web app only) | `sequences:write` |
| POST | `/v1/ad-audiences/:id/pause` | Pause or resume syncing an audience (web app only) | `sequences:write` |
| GET | `/v1/external-campaigns` | Draft and live campaigns in external sequencers (Instantly, Smartlead) | `sequences:read` |
| POST | `/v1/external-campaigns` | Create a draft campaign in Instantly or Smartlead from a sequence's copy, and upload the eligible people (exclusions are reported) (web app only) | `sequences:write` |
| GET | `/v1/external-campaigns/:id` | A campaign with its leads (uploaded, excluded and why, replied, bounced, unsubscribed, removed) | `sequences:read` |
| POST | `/v1/external-campaigns/:id/activate` | Launch the campaign in the vendor (an organization owner, signed in, confirming the lead count they saw) (web app only) | `messages:send` |
| GET | `/v1/external-campaigns/:id/activation` | What launching would send: lead count, copy, schedule and the vendor's sending accounts | `sequences:read` |
| POST | `/v1/external-campaigns/:id/leads` | Upload more people (a list or contacts); people already uploaded are skipped (web app only) | `messages:send` |
| POST | `/v1/external-campaigns/:id/pause` | Pause the campaign in the vendor | `sequences:write` |
| GET | `/v1/gifts` | Gifts asked for (yours; everyone's for an organization owner) and their status | `sequences:read` |
| POST | `/v1/gifts` | Ask for a gift for a contact (an organization owner approves the item, cost, recipient and reason before it's sent) (web app only) | `sequences:write` |
| POST | `/v1/gifts/:id/decide` | Approve (send through Sendoso) or reject a gift (an organization owner, signed in) (web app only) | `sequences:write` |
| GET | `/v1/linkedin/comments` | LinkedIn comments drafted for you (waiting for your approval, and done) | `sequences:read` |
| POST | `/v1/linkedin/comments/:id/decide` | Approve (post it from your LinkedIn account; you may edit it) or reject a drafted comment (web app only) | `messages:send` |
| POST | `/v1/linkedin/refresh` | Fill in names and headlines on contacts you're connected to on LinkedIn (once a day) (web app only) | `contacts:write` |
| GET | `/v1/sending-domains` | Sending domains: source, mailboxes, cost, renewal date and status | `settings:read` |
| POST | `/v1/sending-domains` | Buy a sending domain at Cloudflare (an organization owner approving the live price, the renewal price, and that it can't be refunded) (web app only) | `settings:write` |
| POST | `/v1/sending-domains/:id/cancel` | Stop tracking a domain (and how to cancel it at the registrar or vendor) (web app only) | `settings:write` |
| POST | `/v1/sending-domains/:id/paid` | An Instantly order that needed checkout is paid (an organization owner) (web app only) | `settings:write` |
| POST | `/v1/sending-domains/candidates` | Lookalikes of one of your own domains, with live availability and prices (Cloudflare Registrar) (web app only) | `settings:write` |
| POST | `/v1/sending-domains/instantly-orders` | Quote (no approve_total) or buy (an organization owner approving the quoted total) an Instantly done-for-you or pre-warmed domain (web app only) | `settings:write` |
| GET | `/v1/sending-domains/prewarmed` | Pre-warmed domains Instantly offers (provider per domain; an owner, signed in) (web app only) | `settings:write` |
| GET | `/v1/sending-domains/verification` | The DNS TXT record proving you control a primary domain (needed before lookalikes of it) | `settings:read` |
| GET | `/v1/vendors` | Paid vendors this organization can connect with its own account (never the credentials) | `settings:read` |
| PUT | `/v1/vendors/:vendor` | Connect, turn on or off, or configure a paid vendor with your own credentials (organization owners, signed in; stored encrypted) (web app only) | `integrations:write` |
| POST | `/v1/vendors/:vendor/check` | Check the saved credentials with a harmless read (web app only) | `integrations:write` |
| DELETE | `/v1/vendors/:vendor/credentials` | Remove a vendor's credentials (turns it off) (web app only) | `integrations:write` |
| POST | `/v1/vendors/unipile/webhooks` | Register this organization's Unipile webhooks (acceptances, messages) for its mapped LinkedIn accounts (web app only) | `integrations:write` |
| GET | `/v1/warmup` | Warmup per mailbox (ramping, ready, cooling down, paused, not in the vendor) with today's cap; and the risk | `settings:read` |

## Examples

### GET /v1/ad-audiences

Ad audiences synced from segments, with status and match rate per destination

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

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

### GET /v1/external-campaigns

Draft and live campaigns in external sequencers (Instantly, Smartlead)

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

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

### GET /v1/external-campaigns/$ID

A campaign with its leads (uploaded, excluded and why, replied, bounced, unsubscribed, removed)

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

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

### GET /v1/external-campaigns/$ID/activation

What launching would send: lead count, copy, schedule and the vendor's sending accounts

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

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

### POST /v1/external-campaigns/$ID/pause

Pause the campaign in the vendor

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

```js
const res = await fetch(`https://api.closefinch.com/v1/external-campaigns/${id}/pause`, {
  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/gifts

Gifts asked for (yours; everyone's for an organization owner) and their status

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

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

### GET /v1/linkedin/comments

LinkedIn comments drafted for you (waiting for your approval, and done)

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

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

### GET /v1/sending-domains

Sending domains: source, mailboxes, cost, renewal date and status

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

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

### GET /v1/sending-domains/verification

The DNS TXT record proving you control a primary domain (needed before lookalikes of it)

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

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

### GET /v1/vendors

Paid vendors this organization can connect with its own account (never the credentials)

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

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

### GET /v1/warmup

Warmup per mailbox (ramping, ready, cooling down, paused, not in the vendor) with today's cap; and the risk

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

```js
const res = await fetch(`https://api.closefinch.com/v1/warmup`, {
  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](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
