# OpenSend API

Transactional and marketing email. 202 means queued, not delivered. Sending is simulated when live SES is disabled or AWS credentials are not configured.

- [Interactive documentation](/docs)
- [OpenAPI 3.1 JSON](/openapi.json)
- [Agent index](/llms.txt)
- TypeScript package: `opensend-js`

## Auth

- [List MCP connections](/docs/operations/listMcpConnections.md) — `GET /v1/mcp-connections`
- [Revoke MCP connection](/docs/operations/revokeMcpConnection.md) — `POST /v1/mcp-connections/{id}/revoke`
- [Get current identity](/docs/operations/getCurrentIdentity.md) — `GET /v1/me`
- [List agent tokens](/docs/operations/listAgentTokens.md) — `GET /v1/agent-tokens`
- [Create agent token](/docs/operations/createAgentToken.md) — `POST /v1/agent-tokens`
- [Revoke agent token](/docs/operations/revokeAgentToken.md) — `POST /v1/agent-tokens/{id}/revoke`

## ApiKeys

- [List api keys](/docs/operations/listApiKeys.md) — `GET /v1/api-keys`
- [Create api key](/docs/operations/createApiKey.md) — `POST /v1/api-keys`
- [Revoke api key](/docs/operations/revokeApiKey.md) — `POST /v1/api-keys/{id}/revoke`

## Audience

- [List contacts](/docs/operations/listContacts.md) — `GET /v1/contacts`
- [Create contact](/docs/operations/createContact.md) — `POST /v1/contacts`
- [Get contact](/docs/operations/getContact.md) — `GET /v1/contacts/{id}`
- [Update contact](/docs/operations/updateContact.md) — `PATCH /v1/contacts/{id}`
- [Delete contact](/docs/operations/deleteContact.md) — `DELETE /v1/contacts/{id}`
- [List contact lists](/docs/operations/listContactLists.md) — `GET /v1/lists`
- [Create contact list](/docs/operations/createContactList.md) — `POST /v1/lists`
- [Get contact list](/docs/operations/getContactList.md) — `GET /v1/lists/{id}`
- [Update contact list](/docs/operations/updateContactList.md) — `PATCH /v1/lists/{id}`
- [Delete contact list](/docs/operations/deleteContactList.md) — `DELETE /v1/lists/{id}`
- [List list members](/docs/operations/listListMembers.md) — `GET /v1/lists/{id}/members`
- [Add list members](/docs/operations/addListMembers.md) — `POST /v1/lists/{id}/members`
- [Remove list member](/docs/operations/removeListMember.md) — `DELETE /v1/lists/{id}/members/{contactId}`
- [List segments](/docs/operations/listSegments.md) — `GET /v1/segments`
- [Create segment](/docs/operations/createSegment.md) — `POST /v1/segments`
- [Get segment](/docs/operations/getSegment.md) — `GET /v1/segments/{id}`
- [Update segment](/docs/operations/updateSegment.md) — `PATCH /v1/segments/{id}`
- [Delete segment](/docs/operations/deleteSegment.md) — `DELETE /v1/segments/{id}`
- [Preview segment](/docs/operations/previewSegment.md) — `POST /v1/segments/{id}/preview`
- [List contact imports](/docs/operations/listContactImports.md) — `GET /v1/contact-imports`
- [Preview contact import](/docs/operations/previewContactImport.md) — `POST /v1/contact-imports`
- [Get contact import](/docs/operations/getContactImport.md) — `GET /v1/contact-imports/{id}`
- [Commit contact import](/docs/operations/commitContactImport.md) — `POST /v1/contact-imports/{id}/commit`
- [Query audience](/docs/operations/queryAudience.md) — `POST /v1/audience-query/query`
- [Plan audience mutation](/docs/operations/planAudienceMutation.md) — `POST /v1/audience-query/plan`
- [Apply audience plan](/docs/operations/applyAudiencePlan.md) — `POST /v1/audience-query/apply`

## Consent

- [List contact consent events](/docs/operations/listContactConsentEvents.md) — `GET /v1/contacts/{id}/consent`
- [Update contact consent](/docs/operations/updateContactConsent.md) — `POST /v1/contacts/{id}/consent`
- [Unsubscribe by link](/docs/operations/unsubscribeByLink.md) — `GET /unsubscribe/{token}`
- [Unsubscribe one click](/docs/operations/unsubscribeOneClick.md) — `POST /unsubscribe/{token}`

## Templates

- [List campaign templates](/docs/operations/listCampaignTemplates.md) — `GET /v1/templates`
- [Create campaign template](/docs/operations/createCampaignTemplate.md) — `POST /v1/templates`
- [Get campaign template](/docs/operations/getCampaignTemplate.md) — `GET /v1/templates/{id}`
- [Update campaign template](/docs/operations/updateCampaignTemplate.md) — `PATCH /v1/templates/{id}`
- [Delete campaign template](/docs/operations/deleteCampaignTemplate.md) — `DELETE /v1/templates/{id}`
- [Publish campaign template](/docs/operations/publishCampaignTemplate.md) — `POST /v1/templates/{id}/publish`
- [Preview campaign template](/docs/operations/previewCampaignTemplate.md) — `GET /v1/templates/{id}/preview`
- [Render campaign template preview image](/docs/operations/renderCampaignTemplatePreviewImage.md) — `GET /v1/templates/{id}/preview-image`
- [Set campaign template archived](/docs/operations/setCampaignTemplateArchived.md) — `PATCH /v1/templates/{id}/archive`
- [Upload template asset](/docs/operations/uploadTemplateAsset.md) — `POST /v1/template-assets`
- [Import template image](/docs/operations/importTemplateImage.md) — `POST /v1/template-assets/import`
- [Get template asset](/docs/operations/getTemplateAsset.md) — `GET /v1/template-assets/{id}`
- [Delete template asset](/docs/operations/deleteTemplateAsset.md) — `DELETE /v1/template-assets/{id}`
- [Get template asset content](/docs/operations/getTemplateAssetContent.md) — `GET /v1/template-assets/{id}/content`

## Emails

- [Send email](/docs/operations/sendEmail.md) — `POST /v1/emails/send`
- [Send email batch](/docs/operations/sendEmailBatch.md) — `POST /v1/emails/batch`
- [List emails](/docs/operations/listEmails.md) — `GET /v1/emails`
- [Get email](/docs/operations/getEmail.md) — `GET /v1/emails/{id}`
- [Get email detail](/docs/operations/getEmailDetail.md) — `GET /v1/emails/{id}/detail`
- [Get email content](/docs/operations/getEmailContent.md) — `GET /v1/emails/{id}/content`
- [List email events](/docs/operations/listEmailEvents.md) — `GET /v1/emails/{id}/events`

## Attachments

- [Upload attachment](/docs/operations/uploadAttachment.md) — `POST /v1/attachments`
- [Get attachment](/docs/operations/getAttachment.md) — `GET /v1/attachments/{id}`
- [Delete attachment](/docs/operations/deleteAttachment.md) — `DELETE /v1/attachments/{id}`
- [Get attachment content](/docs/operations/getAttachmentContent.md) — `GET /v1/attachments/{id}/content`

## Campaigns

- [List campaigns](/docs/operations/listCampaigns.md) — `GET /v1/campaigns`
- [Create campaign](/docs/operations/createCampaign.md) — `POST /v1/campaigns`
- [Get campaign](/docs/operations/getCampaign.md) — `GET /v1/campaigns/{id}`
- [Update campaign](/docs/operations/updateCampaign.md) — `PATCH /v1/campaigns/{id}`
- [Delete campaign](/docs/operations/deleteCampaign.md) — `DELETE /v1/campaigns/{id}`
- [Get campaign stats](/docs/operations/getCampaignStats.md) — `GET /v1/campaigns/{id}/stats`
- [Get campaign content guide](/docs/operations/getCampaignContentGuide.md) — `GET /v1/campaign-content-guide`
- [Preview campaign](/docs/operations/previewCampaign.md) — `GET /v1/campaigns/{id}/preview`
- [Preview campaign audience](/docs/operations/previewCampaignAudience.md) — `GET /v1/campaigns/{id}/audience`
- [Render campaign preview image](/docs/operations/renderCampaignPreviewImage.md) — `GET /v1/campaigns/{id}/preview-image`
- [Get campaign state](/docs/operations/getCampaignState.md) — `GET /v1/campaigns/{id}/state`
- [Set campaign archived](/docs/operations/setCampaignArchived.md) — `PATCH /v1/campaigns/{id}/archive`
- [Test campaign](/docs/operations/testCampaign.md) — `POST /v1/campaigns/{id}/test`
- [Send campaign](/docs/operations/sendCampaign.md) — `POST /v1/campaigns/{id}/send`
- [Schedule campaign](/docs/operations/scheduleCampaign.md) — `POST /v1/campaigns/{id}/schedule`
- [Cancel campaign](/docs/operations/cancelCampaign.md) — `POST /v1/campaigns/{id}/cancel`
- [Pause campaign](/docs/operations/pauseCampaign.md) — `POST /v1/campaigns/{id}/pause`
- [Resume campaign](/docs/operations/resumeCampaign.md) — `POST /v1/campaigns/{id}/resume`
- [Set campaign pacing](/docs/operations/setCampaignPacing.md) — `POST /v1/campaigns/{id}/pacing`

## Settings

- [Get workspace settings](/docs/operations/getWorkspaceSettings.md) — `GET /v1/settings/workspace`
- [Update workspace settings](/docs/operations/updateWorkspaceSettings.md) — `PATCH /v1/settings/workspace`
- [Get ses settings](/docs/operations/getSesSettings.md) — `GET /v1/settings/ses`

## Domains

- [List domains](/docs/operations/listDomains.md) — `GET /v1/domains`
- [Create domain](/docs/operations/createDomain.md) — `POST /v1/domains`
- [Configure domain mail from](/docs/operations/configureDomainMailFrom.md) — `POST /v1/domains/{id}/mail-from`
- [Get domain dns setup](/docs/operations/getDomainDnsSetup.md) — `GET /v1/domains/{id}/dns-setup`
- [Complete domain dns setup](/docs/operations/completeDomainDnsSetup.md) — `GET /v1/domains/{id}/dns-setup/return/{token}`
- [Get domain](/docs/operations/getDomain.md) — `GET /v1/domains/{id}`
- [Delete domain](/docs/operations/deleteDomain.md) — `DELETE /v1/domains/{id}`
- [Verify domain](/docs/operations/verifyDomain.md) — `POST /v1/domains/{id}/verify`

## Webhooks

- [List webhooks](/docs/operations/listWebhooks.md) — `GET /v1/webhooks`
- [Create webhook](/docs/operations/createWebhook.md) — `POST /v1/webhooks`
- [Get webhook](/docs/operations/getWebhook.md) — `GET /v1/webhooks/{id}`
- [Update webhook](/docs/operations/updateWebhook.md) — `PATCH /v1/webhooks/{id}`
- [Delete webhook](/docs/operations/deleteWebhook.md) — `DELETE /v1/webhooks/{id}`
- [Reveal webhook secret](/docs/operations/revealWebhookSecret.md) — `GET /v1/webhooks/{id}/secret`
- [Rotate webhook secret](/docs/operations/rotateWebhookSecret.md) — `POST /v1/webhooks/{id}/rotate-secret`
- [Test webhook](/docs/operations/testWebhook.md) — `POST /v1/webhooks/{id}/test`
- [List webhook deliveries](/docs/operations/listWebhookDeliveries.md) — `GET /v1/webhooks/{id}/deliveries`
- [Get webhook delivery](/docs/operations/getWebhookDelivery.md) — `GET /v1/webhooks/{id}/deliveries/{deliveryId}`
- [Retry webhook delivery](/docs/operations/retryWebhookDelivery.md) — `POST /v1/webhooks/{id}/deliveries/{deliveryId}/retry`

## Events

- [Receive ses sns event](/docs/operations/receiveSesSnsEvent.md) — `POST /v1/events/ses`

## Metrics

- [Get metrics](/docs/operations/getMetrics.md) — `GET /v1/metrics`

## Regions

- [List regions](/docs/operations/listRegions.md) — `GET /v1/regions`
- [Configure region](/docs/operations/configureRegion.md) — `PUT /v1/regions/{region}`
- [Discover region](/docs/operations/discoverRegion.md) — `GET /v1/regions/{region}/discovery`
- [Provision region](/docs/operations/provisionRegion.md) — `POST /v1/regions/{region}/provision`
- [Configure region auto validation](/docs/operations/configureRegionAutoValidation.md) — `PUT /v1/regions/{region}/auto-validation`

## Inbound domains

- [List inbound domains](/docs/operations/listInboundDomains.md) — `GET /v1/inbound/domains`
- [Get inbound domain](/docs/operations/getInboundDomain.md) — `GET /v1/inbound/domains/{id}`
- [Update inbound domain](/docs/operations/updateInboundDomain.md) — `PATCH /v1/inbound/domains/{id}`
- [Check inbound domain](/docs/operations/checkInboundDomain.md) — `POST /v1/inbound/domains/{id}/check`
- [Enable inbound domain](/docs/operations/enableInboundDomain.md) — `POST /v1/inbound/domains/{id}/enable`
- [Disable inbound domain](/docs/operations/disableInboundDomain.md) — `POST /v1/inbound/domains/{id}/disable`
- [List inbound subdomains](/docs/operations/listInboundSubdomains.md) — `GET /v1/inbound/domains/{id}/subdomains`
- [Create inbound subdomain](/docs/operations/createInboundSubdomain.md) — `POST /v1/inbound/domains/{id}/subdomains`
- [Get inbound subdomain](/docs/operations/getInboundSubdomain.md) — `GET /v1/inbound/domains/{id}/subdomains/{subdomainId}`
- [Update inbound subdomain](/docs/operations/updateInboundSubdomain.md) — `PATCH /v1/inbound/domains/{id}/subdomains/{subdomainId}`
- [Remove inbound subdomain](/docs/operations/removeInboundSubdomain.md) — `DELETE /v1/inbound/domains/{id}/subdomains/{subdomainId}`

## Inbound addresses

- [List inbound addresses](/docs/operations/listInboundAddresses.md) — `GET /v1/inbound/addresses`
- [Create inbound address](/docs/operations/createInboundAddress.md) — `POST /v1/inbound/addresses`
- [Get inbound address](/docs/operations/getInboundAddress.md) — `GET /v1/inbound/addresses/{addressId}`
- [Update inbound address](/docs/operations/updateInboundAddress.md) — `PATCH /v1/inbound/addresses/{addressId}`
- [Delete inbound address](/docs/operations/deleteInboundAddress.md) — `DELETE /v1/inbound/addresses/{addressId}`

## Inbound threads

- [List inbound threads](/docs/operations/listInboundThreads.md) — `GET /v1/inbound/threads`
- [Create inbound thread](/docs/operations/createInboundThread.md) — `POST /v1/inbound/threads`
- [Get inbound thread](/docs/operations/getInboundThread.md) — `GET /v1/inbound/threads/{threadId}`
- [Update inbound thread](/docs/operations/updateInboundThread.md) — `PATCH /v1/inbound/threads/{threadId}`
- [List inbound messages](/docs/operations/listInboundMessages.md) — `GET /v1/inbound/messages`
- [Get inbound message](/docs/operations/getInboundMessage.md) — `GET /v1/inbound/messages/{messageId}`
- [Get inbound attachment](/docs/operations/getInboundAttachment.md) — `GET /v1/inbound/messages/{messageId}/attachments/{attachmentId}`
- [Reply to inbound thread](/docs/operations/replyToInboundThread.md) — `POST /v1/inbound/threads/{threadId}/reply`

## Inbound events

- [List inbound events](/docs/operations/listInboundEvents.md) — `GET /v1/inbound/events`

## Inbound keys

- [List inbound keys](/docs/operations/listInboundKeys.md) — `GET /v1/inbound/keys`
- [Create inbound key](/docs/operations/createInboundKey.md) — `POST /v1/inbound/keys`
- [Revoke inbound key](/docs/operations/revokeInboundKey.md) — `POST /v1/inbound/keys/{id}/revoke`

## Inbound webhooks

- [List inbound webhooks](/docs/operations/listInboundWebhooks.md) — `GET /v1/inbound/webhooks`
- [Create inbound webhook](/docs/operations/createInboundWebhook.md) — `POST /v1/inbound/webhooks`
- [Get inbound webhook](/docs/operations/getInboundWebhook.md) — `GET /v1/inbound/webhooks/{id}`
- [Update inbound webhook](/docs/operations/updateInboundWebhook.md) — `PATCH /v1/inbound/webhooks/{id}`
- [Delete inbound webhook](/docs/operations/deleteInboundWebhook.md) — `DELETE /v1/inbound/webhooks/{id}`
- [Rotate inbound webhook secret](/docs/operations/rotateInboundWebhookSecret.md) — `POST /v1/inbound/webhooks/{id}/rotate-secret`
- [List inbound webhook deliveries](/docs/operations/listInboundWebhookDeliveries.md) — `GET /v1/inbound/webhooks/{id}/deliveries`

## Workspaces

- [List workspaces](/docs/operations/listWorkspaces.md) — `GET /v1/workspaces`
- [Create workspace](/docs/operations/createWorkspace.md) — `POST /v1/workspaces`
- [Rename current workspace](/docs/operations/renameCurrentWorkspace.md) — `PATCH /v1/workspaces/current`
- [List workspace members](/docs/operations/listWorkspaceMembers.md) — `GET /v1/workspaces/current/members`
- [Invite workspace member](/docs/operations/inviteWorkspaceMember.md) — `POST /v1/workspaces/current/members`
- [List workspace invitations](/docs/operations/listWorkspaceInvitations.md) — `GET /v1/workspaces/current/invitations`
- [Create workspace invitation](/docs/operations/createWorkspaceInvitation.md) — `POST /v1/workspaces/current/invitations`
- [Revoke workspace invitation](/docs/operations/revokeWorkspaceInvitation.md) — `DELETE /v1/workspaces/current/invitations`
- [Update workspace member](/docs/operations/updateWorkspaceMember.md) — `PATCH /v1/workspaces/current/members/{id}`
- [Remove workspace member](/docs/operations/removeWorkspaceMember.md) — `DELETE /v1/workspaces/current/members/{id}`
- [Accept workspace invitation](/docs/operations/acceptWorkspaceInvitation.md) — `POST /v1/workspaces/invitations/{id}/accept`
- [Get connection](/docs/operations/getConnection.md) — `GET /v1/connection`
- [Create connection](/docs/operations/createConnection.md) — `POST /v1/connection`
- [Delete connection](/docs/operations/deleteConnection.md) — `DELETE /v1/connection`
- [List connection regions](/docs/operations/listConnectionRegions.md) — `GET /v1/connection/regions`
- [Refresh connection scan](/docs/operations/refreshConnectionScan.md) — `POST /v1/connection/scan`
- [Import connection domains](/docs/operations/importConnectionDomains.md) — `POST /v1/connection/imports`
- [Get connection region status](/docs/operations/getConnectionRegionStatus.md) — `GET /v1/connection/regions/status`
- [Verify connection](/docs/operations/verifyConnection.md) — `POST /v1/connection/verify`

## List MCP connections

`GET /v1/mcp-connections`



Operation ID: `listMcpConnections`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listMcpConnections } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listMcpConnections({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/mcp-connections' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Revoke MCP connection

`POST /v1/mcp-connections/{id}/revoke`



Operation ID: `revokeMcpConnection`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revokeMcpConnection } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await revokeMcpConnection({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/mcp-connections/resource_123/revoke' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get current identity

`GET /v1/me`



Operation ID: `getCurrentIdentity`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCurrentIdentity } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCurrentIdentity({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/me' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List agent tokens

`GET /v1/agent-tokens`



Operation ID: `listAgentTokens`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `includeInactive` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listAgentTokens } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listAgentTokens({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/agent-tokens' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create agent token

`POST /v1/agent-tokens`

Creates a nonrefreshable, short-lived API token for temporary uncommitted scripts. Requires an MCP OAuth principal and cannot delegate permissions beyond that originating approval. Manage tokens cannot administer credentials.

Operation ID: `createAgentToken`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `permissions` | string[] | yes |  |
| `expiresInSeconds` | integer | yes |  |
| `domains` | string[] | no |  |
| `purpose` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createAgentToken } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createAgentToken({
  client,
  body: {
    "permissions": [
      "read"
    ],
    "expiresInSeconds": 30,
    "domains": [],
    "purpose": "Your message is ready."
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/agent-tokens' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "permissions": [
    "read"
  ],
  "expiresInSeconds": 30,
  "domains": [],
  "purpose": "Your message is ready."
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Revoke agent token

`POST /v1/agent-tokens/{id}/revoke`



Operation ID: `revokeAgentToken`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revokeAgentToken } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await revokeAgentToken({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/agent-tokens/resource_123/revoke' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List api keys

`GET /v1/api-keys`



Operation ID: `listApiKeys`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `includeRevoked` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listApiKeys } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listApiKeys({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/api-keys' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create api key

`POST /v1/api-keys`



Operation ID: `createApiKey`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `permissions` | string[] | no |  |
| `domains` | string[] | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createApiKey } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createApiKey({
  client,
  body: {
    "name": "Example",
    "permissions": [
      "send"
    ],
    "domains": []
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/api-keys' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "permissions": [
    "send"
  ],
  "domains": []
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Revoke api key

`POST /v1/api-keys/{id}/revoke`



Operation ID: `revokeApiKey`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revokeApiKey } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await revokeApiKey({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/api-keys/resource_123/revoke' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List contacts

`GET /v1/contacts`

Active contacts with current list IDs. Search is a case-insensitive literal email/name substring. Consent and suppression filters are independent.

Operation ID: `listContacts`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `search` | query | string | no |  |
| `email` | query | string | no | Exact, case-insensitive email match. Uses the unique email index; prefer it over search for one address. |
| `consent` | query | string | no |  |
| `suppressed` | query | string | no |  |
| `listId` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listContacts } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listContacts({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/contacts' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create contact

`POST /v1/contacts`



Operation ID: `createContact`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | yes |  |
| `name` | string | no |  |
| `properties` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createContact } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createContact({
  client,
  body: {
    "email": "recipient@example.com",
    "properties": {}
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/contacts' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "email": "recipient@example.com",
  "properties": {}
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get contact

`GET /v1/contacts/{id}`



Operation ID: `getContact`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getContact } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getContact({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/contacts/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update contact

`PATCH /v1/contacts/{id}`



Operation ID: `updateContact`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string or null | no |  |
| `properties` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateContact } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateContact({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/contacts/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete contact

`DELETE /v1/contacts/{id}`

Remove contact profile and memberships, retaining minimal consent/suppression to prevent accidental re-enrollment.

Operation ID: `deleteContact`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteContact } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteContact({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/contacts/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List contact consent events

`GET /v1/contacts/{id}/consent`



Operation ID: `listContactConsentEvents`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listContactConsentEvents } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listContactConsentEvents({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/contacts/resource_123/consent' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update contact consent

`POST /v1/contacts/{id}/consent`

Set marketing subscription status. Source, policy version, evidence and occurrence time are optional audit context; OpenSend records the actor and current time when omitted. Does not lift delivery suppression. Imports/profile edits cannot establish consent.

Operation ID: `updateContactConsent`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string | yes |  |
| `source` | string | no |  |
| `policyVersion` | string | no |  |
| `evidence` | string | no |  |
| `occurredAt` | string | no |  |
| `confirmResubscribe` | boolean | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateContactConsent } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateContactConsent({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "status": "subscribed",
    "confirmResubscribe": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/contacts/resource_123/consent' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "status": "subscribed",
  "confirmResubscribe": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List contact lists

`GET /v1/lists`



Operation ID: `listContactLists`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `search` | query | string | no |  |
| `counts` | query | string | no | false skips member counts (counts is null), for pickers that only need names. Counting scans every membership of each list. |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listContactLists } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listContactLists({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/lists' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create contact list

`POST /v1/lists`



Operation ID: `createContactList`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `description` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createContactList } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createContactList({
  client,
  body: {
    "name": "Example",
    "description": ""
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/lists' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "description": ""
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get contact list

`GET /v1/lists/{id}`



Operation ID: `getContactList`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getContactList } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getContactList({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update contact list

`PATCH /v1/lists/{id}`



Operation ID: `updateContactList`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no |  |
| `description` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateContactList } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateContactList({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "description": ""
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "description": ""
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete contact list

`DELETE /v1/lists/{id}`



Operation ID: `deleteContactList`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteContactList } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteContactList({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List list members

`GET /v1/lists/{id}/members`



Operation ID: `listListMembers`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `search` | query | string | no |  |
| `email` | query | string | no | Exact, case-insensitive email match. Uses the unique email index; prefer it over search for one address. |
| `consent` | query | string | no |  |
| `suppressed` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listListMembers } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listListMembers({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123/members' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Add list members

`POST /v1/lists/{id}/members`



Operation ID: `addListMembers`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `contactIds` | string[] | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { addListMembers } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await addListMembers({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "contactIds": [
      "contact_123"
    ]
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123/members' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "contactIds": [
    "contact_123"
  ]
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Remove list member

`DELETE /v1/lists/{id}/members/{contactId}`



Operation ID: `removeListMember`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `contactId` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { removeListMember } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await removeListMember({
  client,
  path: {
    "id": "resource_123",
    "contactId": "contact_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/lists/resource_123/members/contact_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List segments

`GET /v1/segments`



Operation ID: `listSegments`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `search` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listSegments } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listSegments({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/segments' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create segment

`POST /v1/segments`



Operation ID: `createSegment`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `rule` | object or object or object | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createSegment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createSegment({
  client,
  body: {
    "name": "Example",
    "rule": {
      "field": "email",
      "operator": "eq",
      "value": "example"
    }
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/segments' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "rule": {
    "field": "email",
    "operator": "eq",
    "value": "example"
  }
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get segment

`GET /v1/segments/{id}`



Operation ID: `getSegment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getSegment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getSegment({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/segments/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update segment

`PATCH /v1/segments/{id}`



Operation ID: `updateSegment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | no |  |
| `rule` | object or object or object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateSegment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateSegment({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/segments/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete segment

`DELETE /v1/segments/{id}`



Operation ID: `deleteSegment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteSegment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteSegment({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/segments/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Preview segment

`POST /v1/segments/{id}/preview`

Bounded to 1000 matches. Unknown observation history is never classified as inactive. Counts separate suppressed and other non-consenting contacts.

Operation ID: `previewSegment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `listId` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { previewSegment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await previewSegment({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/segments/resource_123/preview' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List contact imports

`GET /v1/contact-imports`



Operation ID: `listContactImports`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listContactImports } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listContactImports({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/contact-imports' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Preview contact import

`POST /v1/contact-imports`

Persist a preview before commit. Feature limit: 5 MiB UTF-8 CSV, 50,000 rows, 100 columns. Map headers explicitly. Valid rows can commit alongside a retained row-error report; imports never modify consent or suppression.

Operation ID: `previewContactImport`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `csv` | string | yes |  |
| `listId` | string | no |  |
| `mapping` | object | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { previewContactImport } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await previewContactImport({
  client,
  body: {
    "csv": "example",
    "mapping": {
      "email": "recipient@example.com"
    }
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/contact-imports' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "csv": "example",
  "mapping": {
    "email": "recipient@example.com"
  }
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get contact import

`GET /v1/contact-imports/{id}`



Operation ID: `getContactImport`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getContactImport } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getContactImport({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/contact-imports/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Commit contact import

`POST /v1/contact-imports/{id}/commit`



Operation ID: `commitContactImport`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { commitContactImport } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await commitContactImport({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/contact-imports/resource_123/commit' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Query audience

`POST /v1/audience-query/query`

Execute a bounded read-only AudienceQL SELECT against the virtual contacts schema.

Operation ID: `queryAudience`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `statement` | string | yes | AudienceQL statement. Supported: SELECT fields\|count(*) FROM contacts [WHERE ...] [LIMIT n]; UPDATE contacts SET name\|consent\|properties.key = value WHERE ...; ADD contacts TO LIST 'name-or-id' WHERE ...; REMOVE contacts FROM LIST 'name-or-id' WHERE .... WHERE supports AND with =, !=, CONTAINS, IS NULL, IS NOT NULL and timestamp comparisons over id, email, name, consent, suppressed, list, segment, lastOpenAt, lastClickAt and properties.key. No raw tables, joins, comments or semicolons. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { queryAudience } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await queryAudience({
  client,
  body: {
    "statement": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/audience-query/query' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "statement": "example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Plan audience mutation

`POST /v1/audience-query/plan`

Create a 15-minute immutable plan for a bounded AudienceQL bulk mutation. Does not modify contacts or memberships.

Operation ID: `planAudienceMutation`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `statement` | string | yes | AudienceQL statement. Supported: SELECT fields\|count(*) FROM contacts [WHERE ...] [LIMIT n]; UPDATE contacts SET name\|consent\|properties.key = value WHERE ...; ADD contacts TO LIST 'name-or-id' WHERE ...; REMOVE contacts FROM LIST 'name-or-id' WHERE .... WHERE supports AND with =, !=, CONTAINS, IS NULL, IS NOT NULL and timestamp comparisons over id, email, name, consent, suppressed, list, segment, lastOpenAt, lastClickAt and properties.key. No raw tables, joins, comments or semicolons. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { planAudienceMutation } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await planAudienceMutation({
  client,
  body: {
    "statement": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/audience-query/plan' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "statement": "example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Apply audience plan

`POST /v1/audience-query/apply`

Apply an immutable AudienceQL plan once. Prior opt-outs require confirmResubscribe.

Operation ID: `applyAudiencePlan`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `planId` | string | yes |  |
| `confirmResubscribe` | boolean | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { applyAudiencePlan } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await applyAudiencePlan({
  client,
  body: {
    "planId": "plan_123",
    "confirmResubscribe": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/audience-query/apply' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "planId": "plan_123",
  "confirmResubscribe": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List campaign templates

`GET /v1/templates`



Operation ID: `listCampaignTemplates`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `search` | query | string | no |  |
| `archived` | query | string | no |  |
| `publishedOnly` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listCampaignTemplates } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listCampaignTemplates({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/templates' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create campaign template

`POST /v1/templates`



Operation ID: `createCampaignTemplate`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `description` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createCampaignTemplate({
  client,
  body: {
    "name": "Example",
    "description": ""
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/templates' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "description": ""
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get campaign template

`GET /v1/templates/{id}`



Operation ID: `getCampaignTemplate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCampaignTemplate({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update campaign template

`PATCH /v1/templates/{id}`



Operation ID: `updateCampaignTemplate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |
| `draft` | object | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateCampaignTemplate({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "revision": 1,
    "draft": {
      "name": "Example",
      "description": "",
      "subject": "",
      "replyTo": [],
      "attachments": []
    }
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1,
  "draft": {
    "name": "Example",
    "description": "",
    "subject": "",
    "replyTo": [],
    "attachments": []
  }
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete campaign template

`DELETE /v1/templates/{id}`



Operation ID: `deleteCampaignTemplate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteCampaignTemplate({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Publish campaign template

`POST /v1/templates/{id}/publish`



Operation ID: `publishCampaignTemplate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { publishCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await publishCampaignTemplate({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "revision": 1
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123/publish' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Preview campaign template

`GET /v1/templates/{id}/preview`



Operation ID: `previewCampaignTemplate`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `published` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { previewCampaignTemplate } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await previewCampaignTemplate({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123/preview' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Render campaign template preview image

`GET /v1/templates/{id}/preview-image`

Renders a template draft or published revision as a full-page PNG. Inline template assets are embedded, so agents can verify the result without browser automation.

Operation ID: `renderCampaignTemplatePreviewImage`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `published` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { renderCampaignTemplatePreviewImage } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await renderCampaignTemplatePreviewImage({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123/preview-image' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Set campaign template archived

`PATCH /v1/templates/{id}/archive`



Operation ID: `setCampaignTemplateArchived`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `archived` | boolean | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { setCampaignTemplateArchived } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await setCampaignTemplateArchived({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "archived": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/templates/resource_123/archive' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "archived": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Upload template asset

`POST /v1/template-assets`



Operation ID: `uploadTemplateAsset`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filename` | string | yes |  |
| `contentType` | string | no |  |
| `disposition` | string | no |  |
| `contentId` | string | no |  |
| `content` | string | yes | Base64 (standard or URL-safe alphabet; line breaks are accepted). No data URLs. Maximum decoded bytes: 8 MiB. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { uploadTemplateAsset } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await uploadTemplateAsset({
  client,
  body: {
    "filename": "Example",
    "contentType": "application/octet-stream",
    "disposition": "attachment",
    "content": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/template-assets' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "filename": "Example",
  "contentType": "application/octet-stream",
  "disposition": "attachment",
  "content": "example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Import template image

`POST /v1/template-assets/import`

Downloads a public HTTPS PNG, JPEG, GIF or WebP into private global template assets. Add asset.id to draft.attachments and use src in an img block. This is preferred over hotlinking and requires no browser automation or base64 in model context.

Operation ID: `importTemplateImage`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | yes |  |
| `filename` | string | no |  |
| `contentId` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { importTemplateImage } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await importTemplateImage({
  client,
  body: {
    "url": "https://example.com/webhook"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/template-assets/import' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "url": "https://example.com/webhook"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get template asset

`GET /v1/template-assets/{id}`



Operation ID: `getTemplateAsset`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getTemplateAsset } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getTemplateAsset({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/template-assets/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete template asset

`DELETE /v1/template-assets/{id}`



Operation ID: `deleteTemplateAsset`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteTemplateAsset } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteTemplateAsset({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/template-assets/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get template asset content

`GET /v1/template-assets/{id}/content`



Operation ID: `getTemplateAssetContent`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getTemplateAssetContent } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getTemplateAssetContent({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/template-assets/resource_123/content' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Send email

`POST /v1/emails/send`



Operation ID: `sendEmail`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | yes |  |
| `fromName` | string | no |  |
| `to` | string or string[] | yes |  |
| `cc` | string[] | no |  |
| `bcc` | string[] | no |  |
| `replyTo` | string[] | no |  |
| `region` | string | no | Defaults to the installation’s persisted default region when omitted. |
| `kind` | string | no |  |
| `subject` | string | no |  |
| `html` | string | no |  |
| `text` | string | no |  |
| `template` | object | no | Uses native SES stored-template rendering and snapshots its rendered MIME. SES does not automatically escape HTML; callers must escape untrusted HTML-context values. Simulated deployments do not render AWS templates. |
| `attachments` | string[] | no |  |
| `tracking` | boolean | no |  |
| `headers` | object[] | no | Extra MIME headers, up to 20 and 8 KB in total. Any name is allowed except headers OpenSend controls: From, Sender, Reply-To, Return-Path, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Content-*, DKIM-*, ARC-*, Authentication-Results, Received*, Resent-*, X-SES-*, List-Unsubscribe*, Auto-Submitted, and reply, receipt, trace and transport headers (Mail-Reply-To, Mail-Followup-To, Followup-To, Disposition-Notification-*, Return-Receipt-To, Errors-To, Bounces-To, Delivered-To, X-Original-To, DomainKey-*, Feedback-ID, TLS-Required, BIMI-*, Autocrypt*, OpenPGP). In-Reply-To and References must be <id@domain> Message-IDs and thread the message in the recipient's mail client. |
| `screen` | boolean | no | Ask the installation’s content classifier (Jev) whether this message is unsolicited advertising smuggled into a transactional template, e.g. an ad placed in a user-supplied name. Screened messages that look like spam are rejected before delivery with error code CONTENT_REJECTED_SPAM and a reject event; nothing reaches the provider. Transactional messages only; ignored for marketing and when SES is simulated. Skipped (and logged) when the installation has no classifier configured. |
| `replyAddressId` | string | no | Track a conversation through this receivable address. Use explicit subject and text/html. Requires unrestricted manage permission; From and Reply-To must belong to the address. |
| `replyMailboxId` | string | no | Legacy spelling of replyAddressId. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { sendEmail } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await sendEmail({
  client,
  body: {
    "from": "sender@example.com",
    "to": "recipient@example.com",
    "cc": [],
    "bcc": [],
    "replyTo": [],
    "kind": "transactional",
    "attachments": [],
    "subject": "Hello from OpenSend",
    "text": "Your message is ready."
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/emails/send' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "from": "sender@example.com",
  "to": "recipient@example.com",
  "cc": [],
  "bcc": [],
  "replyTo": [],
  "kind": "transactional",
  "attachments": [],
  "subject": "Hello from OpenSend",
  "text": "Your message is ready."
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Send email batch

`POST /v1/emails/batch`



Operation ID: `sendEmailBatch`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `emails` | object[] | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { sendEmailBatch } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await sendEmailBatch({
  client,
  body: {
    "emails": [
      {
        "from": "sender@example.com",
        "to": "recipient@example.com",
        "cc": [],
        "bcc": [],
        "replyTo": [],
        "kind": "transactional",
        "attachments": [],
        "subject": "Hello from OpenSend",
        "text": "Your message is ready."
      }
    ]
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/emails/batch' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "emails": [
    {
      "from": "sender@example.com",
      "to": "recipient@example.com",
      "cc": [],
      "bcc": [],
      "replyTo": [],
      "kind": "transactional",
      "attachments": [],
      "subject": "Hello from OpenSend",
      "text": "Your message is ready."
    }
  ]
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List emails

`GET /v1/emails`



Operation ID: `listEmails`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `campaignId` | query | string | no |  |
| `status` | query | string | no |  |
| `region` | query | string | no |  |
| `kind` | query | string | no |  |
| `search` | query | string | no | Literal case-insensitive substring of sender, To/Cc/Bcc, subject or email/campaign/provider ID. |
| `from` | query | string | no |  |
| `to` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listEmails } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listEmails({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/emails' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get email

`GET /v1/emails/{id}`



Operation ID: `getEmail`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getEmail } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getEmail({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/emails/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get email detail

`GET /v1/emails/{id}/detail`

One log detail: metadata, visible HTML/text, attachment IDs, the first 100 events and active contact for a single To address. Uses the same content and event redaction as their individual endpoints; no raw MIME. Continue events with listEmailEvents.

Operation ID: `getEmailDetail`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getEmailDetail } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getEmailDetail({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/emails/resource_123/detail' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get email content

`GET /v1/emails/{id}/content`

Manage keys receive full snapshots. Other readers receive app unsubscribe tokens redacted from subject/HTML/text and raw MIME withheld (null), since MIME encodings can conceal capabilities. Other transactional bearer links are not sanitized; grant content-read access only to trusted integrations.

Operation ID: `getEmailContent`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getEmailContent } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getEmailContent({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/emails/resource_123/content' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List email events

`GET /v1/emails/{id}/events`



Operation ID: `listEmailEvents`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listEmailEvents } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listEmailEvents({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/emails/resource_123/events' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Upload attachment

`POST /v1/attachments`



Operation ID: `uploadAttachment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `filename` | string | yes |  |
| `contentType` | string | no |  |
| `disposition` | string | no |  |
| `contentId` | string | no |  |
| `content` | string | yes | Base64 (standard or URL-safe alphabet; line breaks are accepted). No data URLs. Maximum decoded bytes: 8 MiB. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { uploadAttachment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await uploadAttachment({
  client,
  body: {
    "filename": "Example",
    "contentType": "application/octet-stream",
    "disposition": "attachment",
    "content": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/attachments' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "filename": "Example",
  "contentType": "application/octet-stream",
  "disposition": "attachment",
  "content": "example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get attachment

`GET /v1/attachments/{id}`



Operation ID: `getAttachment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getAttachment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getAttachment({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/attachments/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete attachment

`DELETE /v1/attachments/{id}`



Operation ID: `deleteAttachment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteAttachment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteAttachment({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/attachments/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get attachment content

`GET /v1/attachments/{id}/content`

Returns the private attachment as canonical base64 JSON, scoped like its metadata. At most 8 MiB decoded; never a public object URL or executable inline response.

Operation ID: `getAttachmentContent`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getAttachmentContent } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getAttachmentContent({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/attachments/resource_123/content' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List campaigns

`GET /v1/campaigns`

Returns bounded campaign metadata summaries. Fetch an individual campaign for its full editable draft; list drafts omit bodies, defaults, attachments and audience exclusions. Dashboard list counts may be cached for up to 60 seconds; API credentials and campaign detail remain exact.

Operation ID: `listCampaigns`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `region` | query | string | no |  |
| `state` | query | string | no | draft: editable. preparing: the audience is frozen and every message is being validated in the background. scheduled: validated and waiting for scheduledAt. sending: recipients are being released into the dispatch queue. paused: releasing stopped by the user or the health check; queued mail still dispatches. done: every recipient was released and dispatched. failed: preparation or releasing failed (delivery.error); edit or launch again. canceled: terminal. |
| `archived` | query | string | no | False lists active campaigns; true lists archived campaigns only. |
| `search` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listCampaigns } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listCampaigns({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create campaign

`POST /v1/campaigns`

Create a campaign draft; only a name is required. templateId copies an active published global template, including its content and assets, into this workspace. With regional MX delivery, drafts can be edited before sender setup is complete; the sender and region are checked when sending a test or launching. Returns a dashboard URL so an agent and user can continue editing together.

Operation ID: `createCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `from` | string or string | no |  |
| `fromName` | string | no |  |
| `previewText` | string | no | Optional preheader text. Inserted as escaped hidden text into each outgoing HTML snapshot; draft HTML is unchanged. When set, supply HTML without its own duplicate preheader. |
| `replyTo` | string[] | no |  |
| `region` | string | no | Defaults to the installation region. With regional MX delivery, omitting region follows the From domain. |
| `regionPinned` | boolean | no | Regional MX only. False follows the From domain; the displayed region is a hint. A supplied region on create or a changed region on edit pins it. To unpin, pass false and omit region. |
| `subject` | string or string | no |  |
| `attachments` | string[] | no |  |
| `tracking` | boolean | no |  |
| `audience` | object | no |  |
| `defaults` | object | no |  |
| `html` | string | no | Block HTML: h1-h3, p, ul/ol, blockquote, pre>code, hr, img, buttons, columns and styled sections with inline formatting. A constrained email-safe style attribute supports color, typography, spacing, borders, radius and dimensions; arbitrary CSS remains rejected. No wrappers, tables, class or id. Call getContentGuide in MCP or GET /v1/campaign-content-guide for the full vocabulary and examples. |
| `templateId` | string | no | Copies the active published revision of this global campaign template into a new independent campaign draft. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createCampaign({
  client,
  body: {
    "name": "Example",
    "from": "sender@example.com",
    "replyTo": [],
    "subject": "Hello from OpenSend",
    "attachments": [],
    "audience": {},
    "defaults": {}
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "from": "sender@example.com",
  "replyTo": [],
  "subject": "Hello from OpenSend",
  "attachments": [],
  "audience": {},
  "defaults": {}
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get campaign

`GET /v1/campaigns/{id}`



Operation ID: `getCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update campaign

`PATCH /v1/campaigns/{id}`

Replace the whole draft at the current revision. Read the campaign first: html is block HTML that people may have edited in the dashboard composer, so send the complete updated html rather than a fragment. Rejected content names the unsupported tag or attribute. A failed campaign becomes a draft again.

Operation ID: `updateCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |
| `draft` | object | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "revision": 1,
    "draft": {
      "name": "Example",
      "from": "sender@example.com",
      "replyTo": [],
      "subject": "Hello from OpenSend",
      "attachments": [],
      "tracking": true,
      "audience": {},
      "defaults": {}
    }
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1,
  "draft": {
    "name": "Example",
    "from": "sender@example.com",
    "replyTo": [],
    "subject": "Hello from OpenSend",
    "attachments": [],
    "tracking": true,
    "audience": {},
    "defaults": {}
  }
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete campaign

`DELETE /v1/campaigns/{id}`



Operation ID: `deleteCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get campaign stats

`GET /v1/campaigns/{id}/stats`

Lifetime campaign delivery and unique open/click statistics, progress, tracking setting and rates with numeric numerators/denominators. Counts distinct emails across all stored feedback, not event occurrences. Delivery/bounce/complaint rates use accepted emails; open/click rates use delivered emails. Both rate counts exclude simulated emails. Rates are fractions, null for zero denominators; engagement rates are also null with tracking disabled. Delivered means receiving-server acceptance, not inbox placement. Engagement includes bots/privacy proxies. Done means dispatch finished; asynchronous feedback can still change totals.

Operation ID: `getCampaignStats`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCampaignStats } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCampaignStats({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/stats' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get campaign content guide

`GET /v1/campaign-content-guide`

The complete campaign and template content vocabulary, personalization syntax, restrictions and examples as Markdown. Read it once before writing or editing html.

Operation ID: `getCampaignContentGuide`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCampaignContentGuide } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCampaignContentGuide({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaign-content-guide' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Preview campaign

`GET /v1/campaigns/{id}/preview`

Renders the saved draft’s block HTML as the styled email and its plain-text alternative, without personalization or the unsubscribe footer. Placeholders remain visible as {{name}}.

Operation ID: `previewCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { previewCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await previewCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/preview' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Preview campaign audience

`GET /v1/campaigns/{id}/audience`

Counts the saved audience right now: matched contacts and how many are eligible, suppressed or unsubscribed. Read-only and never frozen; send or schedule takes its own snapshot and consent is rechecked at dispatch.

Operation ID: `previewCampaignAudience`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { previewCampaignAudience } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await previewCampaignAudience({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/audience' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Render campaign preview image

`GET /v1/campaigns/{id}/preview-image`

Renders the saved campaign draft as a full-page, 720 px wide PNG for visual review. Inline CID images are embedded; remote HTTPS images are loaded by the isolated renderer.

Operation ID: `renderCampaignPreviewImage`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { renderCampaignPreviewImage } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await renderCampaignPreviewImage({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/preview-image' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get campaign state

`GET /v1/campaigns/{id}/state`

Compact authenticated state for draft sync polling; fetch the full campaign with getCampaign when state changes. Compare all returned fields, not only revision: archive and delivery changes need not increment the draft revision. Omits draft content and delivery counts.

Operation ID: `getCampaignState`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getCampaignState } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getCampaignState({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/state' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Set campaign archived

`PATCH /v1/campaigns/{id}/archive`

Archive a campaign to hide it from default lists, or restore it. Preserves its content, revision, delivery state and history. Preparing, scheduled, sending or paused campaigns must finish or be canceled before archiving. Archived campaigns cannot be edited, tested or sent until restored.

Operation ID: `setCampaignArchived`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `archived` | boolean | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { setCampaignArchived } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await setCampaignArchived({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "archived": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/archive' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "archived": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Test campaign

`POST /v1/campaigns/{id}/test`



Operation ID: `testCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `to` | string | yes |  |
| `data` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { testCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await testCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "to": "recipient@example.com",
    "data": {}
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/test' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "to": "recipient@example.com",
  "data": {}
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Send campaign

`POST /v1/campaigns/{id}/send`

Accept the current revision for durable background delivery: the audience is frozen now, every message is validated in the background, then recipients are released into the dispatch queue. The 202 count is accepted recipient intents, not SES acceptance or delivery; poll the campaign for its state.

Operation ID: `sendCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |
| `pacing` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { sendCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await sendCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "revision": 1
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/send' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Schedule campaign

`POST /v1/campaigns/{id}/schedule`

Accept the current revision for durable scheduled delivery. The audience is frozen and validated now; no recipient is materialized or sent before scheduledAt. The 202 count is accepted recipient intents.

Operation ID: `scheduleCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |
| `pacing` | object | no |  |
| `scheduledAt` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { scheduleCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await scheduleCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "revision": 1,
    "scheduledAt": "2026-09-18T19:00:00Z"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/schedule' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1,
  "scheduledAt": "2026-09-18T19:00:00Z"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Cancel campaign

`POST /v1/campaigns/{id}/cancel`

Stop a preparing, scheduled, sending, paused or failed campaign: unreleased recipients are never materialized and queued mail is canceled; mail already attempting or accepted is reported as inFlight.

Operation ID: `cancelCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { cancelCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await cancelCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/cancel' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Pause campaign

`POST /v1/campaigns/{id}/pause`

Stop releasing new recipients. Queued mail (a few seconds of the send rate) still dispatches. Resume continues from the same position; cancel still works while paused.

Operation ID: `pauseCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

Type: `object`

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { pauseCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await pauseCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/pause' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Resume campaign

`POST /v1/campaigns/{id}/resume`

Continue releasing recipients from where a paused campaign stopped, or where a campaign that failed after releasing some recipients stopped (it continues on the same frozen snapshot, never a new one). After an automatic pause, the next health check runs 30 minutes later.

Operation ID: `resumeCampaign`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

Type: `object`

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { resumeCampaign } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await resumeCampaign({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/resume' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Set campaign pacing

`POST /v1/campaigns/{id}/pacing`

Change the daily cap or automatic pause of a scheduled or sending campaign, for example to raise 50,000 to 100,000 per day. Takes effect on the next release.

Operation ID: `setCampaignPacing`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `perDay` | integer or null | yes |  |
| `autoPause` | boolean | no | Omit to keep the current setting. Hosted shared sending always enforces automatic pause; false is rejected. |
| `rateShare` | number | no | Omit to keep the current setting. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { setCampaignPacing } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await setCampaignPacing({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "perDay": 100
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/campaigns/resource_123/pacing' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "perDay": 100
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get workspace settings

`GET /v1/settings/workspace`



Operation ID: `getWorkspaceSettings`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getWorkspaceSettings } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getWorkspaceSettings({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/settings/workspace' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update workspace settings

`PATCH /v1/settings/workspace`



Operation ID: `updateWorkspaceSettings`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateWorkspaceSettings } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateWorkspaceSettings({
  client,
  body: {
    "name": "Example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/settings/workspace' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get ses settings

`GET /v1/settings/ses`



Operation ID: `getSesSettings`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getSesSettings } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getSesSettings({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/settings/ses' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List domains

`GET /v1/domains`

MX returns persisted DNS records and background verification status without AWS calls. Self-hosted installations refresh up to ten identities unless refresh=false.

Operation ID: `listDomains`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |
| `region` | query | string | no |  |
| `refresh` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listDomains } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listDomains({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/domains' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create domain

`POST /v1/domains`



Operation ID: `createDomain`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `region` | string | no | Regional BYO defaults to the first enabled region, otherwise Ohio. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createDomain({
  client,
  body: {
    "name": "Example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/domains' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Configure domain mail from

`POST /v1/domains/{id}/mail-from`

Configure a custom SES MAIL FROM subdomain with fallback to the default amazonses.com MAIL FROM value while DNS is unavailable.

Operation ID: `configureDomainMailFrom`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `mailFromDomain` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { configureDomainMailFrom } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await configureDomainMailFrom({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "mailFromDomain": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123/mail-from' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "mailFromDomain": "example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get domain dns setup

`GET /v1/domains/{id}/dns-setup`

MX owner/admin dashboard only. Returns a signed provider consent URL for eligible pending records, never changes DNS itself. Inline discovery has a three-second budget; unsupported providers and discovery failures fall back to manual DNS. Receiving is offered only after DNS checks find the target empty.

Operation ID: `getDomainDnsSetup`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `groups` | query | string | no | Optional comma-separated subset of pending groups. Only one receiving target is eligible: receiving (@) or receivingReply (reply). mailfrom is available only for email.<domain>; other MAIL FROM names use manual DNS. |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getDomainDnsSetup } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getDomainDnsSetup({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123/dns-setup' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Complete domain dns setup

`GET /v1/domains/{id}/dns-setup/return/{token}`

Browser return from Domain Connect. Validates the ten-minute signed token and the initiating user’s current owner/admin membership in the workspace owning the domain, restores that workspace and returns to the domain page. An invalid or expired token returns to the domain page without changing anything. Success queues normal DNS/SES verification; a replay cannot create a second job. Provider approval is not proof.

Operation ID: `completeDomainDnsSetup`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `token` | path | string | yes |  |
| `state` | query | string | no |  |
| `error` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { completeDomainDnsSetup } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await completeDomainDnsSetup({
  client,
  path: {
    "id": "resource_123",
    "token": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123/dns-setup/return/example' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `303` | Return to the domain in its original workspace. | — |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get domain

`GET /v1/domains/{id}`

On MX, read the stored DNS records and verification status without an AWS call.

Operation ID: `getDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete domain

`DELETE /v1/domains/{id}`

MX only. Delete this claim’s tagged SES identity and release the domain. Does not remove DNS records.

Operation ID: `deleteDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Verify domain

`POST /v1/domains/{id}/verify`

On MX, request a background verification and return the current stored status. Read the domain again for updates.

Operation ID: `verifyDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { verifyDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await verifyDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/domains/resource_123/verify' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List webhooks

`GET /v1/webhooks`



Operation ID: `listWebhooks`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listWebhooks } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listWebhooks({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/webhooks' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create webhook

`POST /v1/webhooks`



Operation ID: `createWebhook`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | yes |  |
| `description` | string | no |  |
| `eventTypes` | string[] | no |  |
| `regions` | array or null | no |  |
| `paused` | boolean | no |  |
| `headers` | object[] | no | Write-only custom HTTP request headers, e.g. Authorization. Up to 10 unique names (case-insensitive) and 8192 UTF-8 bytes of names and values. Omit on update to keep, supply the complete list to replace, or [] to clear. Transport, Cookie and OpenSend delivery headers are reserved. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createWebhook({
  client,
  body: {
    "url": "https://example.com/webhook",
    "description": "",
    "eventTypes": [
      "email.sent",
      "email.delivered",
      "email.bounced",
      "email.complained",
      "email.rejected",
      "email.rendering_failed",
      "email.delivery_delayed"
    ],
    "paused": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/webhooks' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "url": "https://example.com/webhook",
  "description": "",
  "eventTypes": [
    "email.sent",
    "email.delivered",
    "email.bounced",
    "email.complained",
    "email.rejected",
    "email.rendering_failed",
    "email.delivery_delayed"
  ],
  "paused": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get webhook

`GET /v1/webhooks/{id}`



Operation ID: `getWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update webhook

`PATCH /v1/webhooks/{id}`



Operation ID: `updateWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | no |  |
| `description` | string | no |  |
| `eventTypes` | string[] | no |  |
| `regions` | array or null | no |  |
| `paused` | boolean | no |  |
| `headers` | object[] | no | Write-only custom HTTP request headers, e.g. Authorization. Up to 10 unique names (case-insensitive) and 8192 UTF-8 bytes of names and values. Omit on update to keep, supply the complete list to replace, or [] to clear. Transport, Cookie and OpenSend delivery headers are reserved. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete webhook

`DELETE /v1/webhooks/{id}`



Operation ID: `deleteWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Reveal webhook secret

`GET /v1/webhooks/{id}/secret`



Operation ID: `revealWebhookSecret`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revealWebhookSecret } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await revealWebhookSecret({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/secret' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Rotate webhook secret

`POST /v1/webhooks/{id}/rotate-secret`



Operation ID: `rotateWebhookSecret`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { rotateWebhookSecret } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await rotateWebhookSecret({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/rotate-secret' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Test webhook

`POST /v1/webhooks/{id}/test`



Operation ID: `testWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { testWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await testWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/test' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List webhook deliveries

`GET /v1/webhooks/{id}/deliveries`



Operation ID: `listWebhookDeliveries`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listWebhookDeliveries } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listWebhookDeliveries({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/deliveries' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get webhook delivery

`GET /v1/webhooks/{id}/deliveries/{deliveryId}`



Operation ID: `getWebhookDelivery`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `deliveryId` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getWebhookDelivery } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getWebhookDelivery({
  client,
  path: {
    "id": "resource_123",
    "deliveryId": "delivery_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/deliveries/delivery_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Retry webhook delivery

`POST /v1/webhooks/{id}/deliveries/{deliveryId}/retry`



Operation ID: `retryWebhookDelivery`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `deliveryId` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { retryWebhookDelivery } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await retryWebhookDelivery({
  client,
  path: {
    "id": "resource_123",
    "deliveryId": "delivery_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/webhooks/resource_123/deliveries/delivery_123/retry' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Receive ses sns event

`POST /v1/events/ses`



Operation ID: `receiveSesSnsEvent`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `Type` | string | yes |  |
| `MessageId` | string | yes |  |
| `TopicArn` | string | yes |  |
| `Message` | string | yes |  |
| `Timestamp` | string | yes |  |
| `SignatureVersion` | string | yes |  |
| `Signature` | string | yes |  |
| `SigningCertURL` | string | yes |  |
| `Subject` | string | no |  |
| `SubscribeURL` | string | no |  |
| `Token` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { receiveSesSnsEvent } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await receiveSesSnsEvent({
  client,
  body: {
    "Type": "Notification",
    "MessageId": "message_123",
    "TopicArn": "example",
    "Message": "example",
    "Timestamp": "2026-09-18T19:00:00Z",
    "SignatureVersion": "1",
    "Signature": "example",
    "SigningCertURL": "https://example.com/webhook"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/events/ses' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "Type": "Notification",
  "MessageId": "message_123",
  "TopicArn": "example",
  "Message": "example",
  "Timestamp": "2026-09-18T19:00:00Z",
  "SignatureVersion": "1",
  "Signature": "example",
  "SigningCertURL": "https://example.com/webhook"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Unsubscribe by link

`GET /unsubscribe/{token}`



Operation ID: `unsubscribeByLink`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `token` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { unsubscribeByLink } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await unsubscribeByLink({
  client,
  path: {
    "token": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/unsubscribe/example' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Confirmation page; GET never changes consent (link scanners prefetch footer links). | — |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Unsubscribe one click

`POST /unsubscribe/{token}`



Operation ID: `unsubscribeOneClick`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `token` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { unsubscribeOneClick } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await unsubscribeOneClick({
  client,
  path: {
    "token": "example"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/unsubscribe/example' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Marketing consent is now unsubscribed (RFC 8058 one-click or the confirmation form). | — |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get metrics

`GET /v1/metrics`

Operational created-cohort metrics, not invoicing or provider reputation. Dashboard sessions may receive results cached for up to 60 seconds; API keys, MCP and agent tokens always get fresh results. Selects emails created in [from,to), scoped by email region and stream. Outcomes use current email state and all recorded events, including events after to; this is not a historical state snapshot. Each outcome counts distinct emails, so replays do not inflate counts and outcomes may overlap. Accepted (bucket sent) means evidence of provider acceptance, not merely queued/created. Daily UTC creation buckets contain count=created emails. Granularity defaults to day; granularity=hour additionally returns hourly UTC creation buckets with canonical ISO dates such as 2026-09-12T01:00:00.000Z, while preserving daily buckets and totals. Absent buckets mean zero created emails and zero outcomes; no moving averages are applied. Engagement is observed, not verified human activity.

Operation ID: `getMetrics`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | query | string | no |  |
| `from` | query | string | no |  |
| `to` | query | string | no |  |
| `stream` | query | string | no |  |
| `granularity` | query | string | no |  |
| `include` | query | string | no | Comma-separated extras computed in the same statement: previous (totals for the window of equal length ending at from) and streams (totals per stream for the window, ignoring the stream filter). |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getMetrics } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getMetrics({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/metrics' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List regions

`GET /v1/regions`

Lists persisted region settings and cached discovery/job status without AWS calls. The environment default only seeds installation settings during migration.

Operation ID: `listRegions`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listRegions } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listRegions({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/regions' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Configure region

`PUT /v1/regions/{region}`

Enable/disable a region or choose the default. Requires unrestricted management access. Disabling never deletes AWS resources or historical mail.

Operation ID: `configureRegion`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `enabled` | boolean | no |  |
| `makeDefault` | boolean | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { configureRegion } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await configureRegion({
  client,
  path: {
    "region": "us-east-1"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PUT \
  --url 'https://opensend.anoma.ly/v1/regions/us-east-1' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Discover region

`GET /v1/regions/{region}/discovery`

Read-only AWS discovery. Caches observations in PostgreSQL for 15 minutes; refresh=true forces AWS reads. Never creates resources or subscribes endpoints. Credential or public-origin changes invalidate the cache.

Operation ID: `discoverRegion`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | path | string | yes |  |
| `refresh` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { discoverRegion } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await discoverRegion({
  client,
  path: {
    "region": "us-east-1"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/regions/us-east-1/discovery' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Provision region

`POST /v1/regions/{region}/provision`

Explicitly queue idempotent setup of OpenSend-owned SES configuration sets, SNS topic/policy/event destinations and signed HTTPS subscription. Never sends email, changes DNS, or grants SES production approval. Repeated requests reuse the active job; inspect listRegions and discovery for completion and remaining blockers.

Operation ID: `provisionRegion`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `confirm` | boolean | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { provisionRegion } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await provisionRegion({
  client,
  path: {
    "region": "us-east-1"
  },
  body: {
    "confirm": true
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/regions/us-east-1/provision' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "confirm": true
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Configure region auto validation

`PUT /v1/regions/{region}/auto-validation`

Set SES Auto Validation for one OpenSend-owned configuration set. This changes real AWS behavior and requires unrestricted management access plus explicit confirmation.

Operation ID: `configureRegionAutoValidation`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `region` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stream` | string | yes |  |
| `mode` | string | yes |  |
| `confirm` | boolean | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { configureRegionAutoValidation } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await configureRegionAutoValidation({
  client,
  path: {
    "region": "us-east-1"
  },
  body: {
    "stream": "transactional",
    "mode": "off",
    "confirm": true
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PUT \
  --url 'https://opensend.anoma.ly/v1/regions/us-east-1/auto-validation' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "stream": "transactional",
  "mode": "off",
  "confirm": true
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound domains

`GET /v1/inbound/domains`



Operation ID: `listInboundDomains`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundDomains } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundDomains({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/domains' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound domain

`GET /v1/inbound/domains/{id}`



Operation ID: `getInboundDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update inbound domain

`PATCH /v1/inbound/domains/{id}`



Operation ID: `updateInboundDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `catchAll` | string | no |  |
| `acceptSubdomains` | boolean | no | Whether the receipt rule also matches every subdomain (.example.com). Turned on by the first subdomain and kept on after that. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateInboundDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateInboundDomain({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Check inbound domain

`POST /v1/inbound/domains/{id}/check`

Reads public DNS and reports who currently receives mail for the domain. Updates the receiving status when inbound is enabled. Never changes DNS or AWS.

Operation ID: `checkInboundDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { checkInboundDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await checkInboundDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/check' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Enable inbound domain

`POST /v1/inbound/domains/{id}/enable`

Checks that the domain is verified in SES and that its MX records will not take mail from another provider, then queues setup: an OpenSend S3 bucket, SNS topic and a catch-all SES receipt rule for the domain. Publish the returned MX record to start receiving. Use force=true to take over a domain whose mail another provider receives today.

Operation ID: `enableInboundDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `catchAll` | string | no |  |
| `force` | boolean | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { enableInboundDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await enableInboundDomain({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "force": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/enable' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "force": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Disable inbound domain

`POST /v1/inbound/domains/{id}/disable`

Removes the domain from the OpenSend receipt rule. Receiving addresses and stored messages are kept.

Operation ID: `disableInboundDomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { disableInboundDomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await disableInboundDomain({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/disable' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound subdomains

`GET /v1/inbound/domains/{id}/subdomains`



Operation ID: `listInboundSubdomains`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `status` | query | string | no |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundSubdomains } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundSubdomains({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/subdomains' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create inbound subdomain

`POST /v1/inbound/domains/{id}/subdomains`

Starts receiving mail for name.example.com under a receiving example.com, with no DNS change or SES verification per subdomain. The first subdomain adds the wildcard recipient (.example.com) to the receipt rule, which takes up to a minute; later ones are live immediately. Publish the returned *.example.com MX record once. Receiving addresses can then be created on the subdomain. Re-adding a removed subdomain restores it.

Operation ID: `createInboundSubdomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes | A label (acme) or the full host (acme.example.com). |
| `catchAll` | string | no | For an unknown recipient, store keeps the message as unrouted (default); create_address creates a receiving address. |
| `metadata` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createInboundSubdomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createInboundSubdomain({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "name": "Example",
    "catchAll": "create_address",
    "metadata": {}
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/subdomains' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "catchAll": "create_address",
  "metadata": {}
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound subdomain

`GET /v1/inbound/domains/{id}/subdomains/{subdomainId}`



Operation ID: `getInboundSubdomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `subdomainId` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundSubdomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundSubdomain({
  client,
  path: {
    "id": "resource_123",
    "subdomainId": "subdomain_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/subdomains/subdomain_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update inbound subdomain

`PATCH /v1/inbound/domains/{id}/subdomains/{subdomainId}`



Operation ID: `updateInboundSubdomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `subdomainId` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `catchAll` | string | no |  |
| `metadata` | object | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateInboundSubdomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateInboundSubdomain({
  client,
  path: {
    "id": "resource_123",
    "subdomainId": "subdomain_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/subdomains/subdomain_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Remove inbound subdomain

`DELETE /v1/inbound/domains/{id}/subdomains/{subdomainId}`

New mail to the subdomain is dropped at ingest. Its receiving addresses and stored messages are kept, and adding the subdomain again restores it. The parent keeps its wildcard recipient, so adding subdomains later is instant; turn it off with PATCH /v1/inbound/domains/{id} acceptSubdomains=false.

Operation ID: `removeInboundSubdomain`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `subdomainId` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { removeInboundSubdomain } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await removeInboundSubdomain({
  client,
  path: {
    "id": "resource_123",
    "subdomainId": "subdomain_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/inbound/domains/resource_123/subdomains/subdomain_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound addresses

`GET /v1/inbound/addresses`

An address key sees only addresses it can access.

Operation ID: `listInboundAddresses`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `domain` | query | string | no |  |
| `origin` | query | string | no |  |
| `q` | query | string | no |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundAddresses } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundAddresses({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/addresses' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create inbound address

`POST /v1/inbound/addresses`

Admin only. The domain must be verified for this workspace; mail arrives once its receiving MX record is active. Permanent addresses claim earlier unrouted mail for their address or rules; temporary addresses start empty. Expiry stops new delivery and sending without deleting history.

Operation ID: `createInboundAddress`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `address` | string | yes |  |
| `displayName` | string or null | no |  |
| `publicAddress` | string | no | Permanent addresses only: immutable default From with the same local part on a strict ancestor domain verified for sending with DKIM in the receiving region. Does not change routing or MX. |
| `ttlSeconds` | integer | no | Lease duration in seconds, 60–2592000 (30 days). Omit for a permanent address. Temporary addresses accept plus-tags, not aliases, wildcard rules or historical backfill. Expiry is fixed at creation. |
| `aliases` | string[] | no |  |
| `rules` | string[] | no | Wildcard address patterns, e.g. support+*@acme.com or *@help.acme.com. |
| `metadata` | object | no |  |
| `sendLimits` | object | no | Override outbound limits. Defaults: perHour 100, perDay 1000, perRecipientPerHour 20, perThreadPer10Minutes 10. 0 blocks sending. |
| `requireDmarc` | boolean | no | Hold received mail without a DMARC pass for its From domain: it is stored with the unverified label and does not emit message.received. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createInboundAddress } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createInboundAddress({
  client,
  body: {
    "address": "example",
    "aliases": [],
    "rules": [],
    "metadata": {},
    "requireDmarc": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/addresses' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "address": "example",
  "aliases": [],
  "rules": [],
  "metadata": {},
  "requireDmarc": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound address

`GET /v1/inbound/addresses/{addressId}`



Operation ID: `getInboundAddress`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `addressId` | path | string | yes | Opaque inbound address ID (mbx_…). |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundAddress } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundAddress({
  client,
  path: {
    "addressId": "address_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/addresses/address_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update inbound address

`PATCH /v1/inbound/addresses/{addressId}`

Admin only. Only supplied fields change. The address, public sender and expiry are immutable.

Operation ID: `updateInboundAddress`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `addressId` | path | string | yes | Opaque inbound address ID (mbx_…). |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `displayName` | string or null | no |  |
| `aliases` | string[] | no |  |
| `rules` | string[] | no |  |
| `metadata` | object | no |  |
| `sendLimits` | object | no | Override outbound limits. Defaults: perHour 100, perDay 1000, perRecipientPerHour 20, perThreadPer10Minutes 10. 0 blocks sending. |
| `requireDmarc` | boolean | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateInboundAddress } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateInboundAddress({
  client,
  path: {
    "addressId": "address_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/inbound/addresses/address_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete inbound address

`DELETE /v1/inbound/addresses/{addressId}`

Admin only. Releases this address and removes its per-address state. Stored messages are kept; future mail follows normal routing.

Operation ID: `deleteInboundAddress`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `addressId` | path | string | yes | Opaque inbound address ID (mbx_…). |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteInboundAddress } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteInboundAddress({
  client,
  path: {
    "addressId": "address_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/inbound/addresses/address_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound threads

`GET /v1/inbound/threads`

Newest visible activity first, then descending thread ID. addressId narrows all projected messages and IDs. q searches visible messages; view matches state on any visible address. all (default) includes trash. Pass nextCursor to continue.

Operation ID: `listInboundThreads`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `addressId` | query | string | no | Opaque inbound address ID (mbx_…). |
| `cursor` | query | string | no | Opaque cursor from the preceding page, with the same filters. |
| `limit` | query | integer | no |  |
| `view` | query | string | no |  |
| `q` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundThreads } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundThreads({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/threads' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create inbound thread

`POST /v1/inbound/threads`



Operation ID: `createInboundThread`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | no | Defaults to the public address if configured, otherwise the primary receiving address. Address keys may use only addresses owned by this mailbox. Administrators may use any address on a domain registered in OpenSend for the receiving region; replies still return to whatever address the recipient answers. |
| `text` | string | no |  |
| `html` | string | no |  |
| `attachments` | object or object[] | no | Up to 20 files, 8 MiB combined. Any type Amazon SES delivers (executables and scripts are refused). |
| `replyTo` | string[] | no |  |
| `headers` | object[] | no | Extra MIME headers, up to 20 and 8 KB in total. Any name is allowed except headers OpenSend controls: From, Sender, Reply-To, Return-Path, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Content-*, DKIM-*, ARC-*, Authentication-Results, Received*, Resent-*, X-SES-*, List-Unsubscribe*, Auto-Submitted, and reply, receipt, trace and transport headers (Mail-Reply-To, Mail-Followup-To, Followup-To, Disposition-Notification-*, Return-Receipt-To, Errors-To, Bounces-To, Delivered-To, X-Original-To, DomainKey-*, Feedback-ID, TLS-Required, BIMI-*, Autocrypt*, OpenPGP). In-Reply-To and References must be <id@domain> Message-IDs and thread the message in the recipient's mail client. |
| `autoSubmitted` | string | no | Adds an RFC 3834 Auto-Submitted header so other automated systems do not reply to this message. |
| `addressId` | string | yes | Opaque inbound address ID (mbx_…). |
| `to` | string[] | yes |  |
| `cc` | string[] | no |  |
| `bcc` | string[] | no |  |
| `subject` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createInboundThread } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createInboundThread({
  client,
  body: {
    "attachments": [],
    "replyTo": [],
    "headers": [],
    "addressId": "address_123",
    "to": [
      "recipient@example.com"
    ],
    "cc": [],
    "bcc": [],
    "subject": "Hello from OpenSend"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/threads' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "attachments": [],
  "replyTo": [],
  "headers": [],
  "addressId": "address_123",
  "to": [
    "recipient@example.com"
  ],
  "cc": [],
  "bcc": [],
  "subject": "Hello from OpenSend"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Queued, not yet delivered. | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound thread

`GET /v1/inbound/threads/{threadId}`

Returns the most recent visible messages (default 25, maximum 100), oldest first within the page. Ties use message ID. Pass nextCursor as cursor for the older page. Body previews are capped at 8192 characters; getInboundMessage retrieves stored text and attachment metadata. State and counts are scoped to visible addresses.

Operation ID: `getInboundThread`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `threadId` | path | string | yes |  |
| `addressId` | query | string | no | Opaque inbound address ID (mbx_…). |
| `cursor` | query | string | no | Opaque cursor from the preceding page, with the same filters. |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundThread } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundThread({
  client,
  path: {
    "threadId": "thread_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/threads/thread_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update inbound thread

`PATCH /v1/inbound/threads/{threadId}`



Operation ID: `updateInboundThread`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `threadId` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `addressId` | string | no | Opaque inbound address ID (mbx_…). |
| `read` | boolean | no |  |
| `archived` | boolean | no |  |
| `starred` | boolean | no |  |
| `trashed` | boolean | no |  |
| `spam` | boolean | no |  |
| `addLabels` | string[] | no |  |
| `removeLabels` | string[] | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateInboundThread } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateInboundThread({
  client,
  path: {
    "threadId": "thread_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/inbound/threads/thread_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound messages

`GET /v1/inbound/messages`

Newest first; default inbound. Unassigned stored mail is visible only to a workspace administrator without an address filter.

Operation ID: `listInboundMessages`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `addressId` | query | string | no | Opaque inbound address ID (mbx_…). |
| `cursor` | query | string | no | Opaque cursor from the preceding page, with the same filters. |
| `limit` | query | integer | no |  |
| `includeDelivery` | query | string | no | Include delivery details for workspace logs (dashboard or unrestricted live manage access only). |
| `region` | query | string | no |  |
| `threadId` | query | string | no |  |
| `direction` | query | string | no |  |
| `q` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundMessages } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundMessages({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/messages' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound message

`GET /v1/inbound/messages/{messageId}`



Operation ID: `getInboundMessage`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `messageId` | path | string | yes |  |
| `addressId` | query | string | no | Opaque inbound address ID (mbx_…). |
| `includeDelivery` | query | string | no | Include delivery details for workspace logs (dashboard or unrestricted live manage access only). |
| `includeHtml` | query | string | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundMessage } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundMessage({
  client,
  path: {
    "messageId": "message_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/messages/message_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound attachment

`GET /v1/inbound/messages/{messageId}/attachments/{attachmentId}`



Operation ID: `getInboundAttachment`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `messageId` | path | string | yes |  |
| `attachmentId` | path | string | yes |  |
| `addressId` | query | string | no | Opaque inbound address ID (mbx_…). |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundAttachment } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundAttachment({
  client,
  path: {
    "messageId": "message_123",
    "attachmentId": "attachment_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/messages/message_123/attachments/attachment_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Reply to inbound thread

`POST /v1/inbound/threads/{threadId}/reply`

Replies to the newest visible message in either direction, breaking time ties by descending message ID. addressId restricts the target and sending address; provide it when the target is linked to more than one visible address. Set replyToMessageId to select an older visible message in this thread. For reviewed replies, pin both IDs and expectedRecipients. A recipient mismatch or a pending outbound parent without a provider Message-ID returns 409.

Operation ID: `replyToInboundThread`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `threadId` | path | string | yes |  |
| `Idempotency-Key` | header | string | no | Optional. Makes retries safe. Repeating a request with the same key and the same body returns the original result without performing the write again; a concurrent duplicate waits for the first request and returns its result. Reusing a key with a different body returns 409 IDEMPOTENCY_CONFLICT. Keys are scoped to the API key and request path, and are retained indefinitely. Without a key, every request is processed, so a retried send can deliver twice. |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `from` | string | no | Defaults to the public address if configured, otherwise the primary receiving address. Address keys may use only addresses owned by this mailbox. Administrators may use any address on a domain registered in OpenSend for the receiving region; replies still return to whatever address the recipient answers. |
| `text` | string | no |  |
| `html` | string | no |  |
| `attachments` | object or object[] | no | Up to 20 files, 8 MiB combined. Any type Amazon SES delivers (executables and scripts are refused). |
| `replyTo` | string[] | no |  |
| `headers` | object[] | no | Extra MIME headers, up to 20 and 8 KB in total. Any name is allowed except headers OpenSend controls: From, Sender, Reply-To, Return-Path, To, Cc, Bcc, Subject, Date, Message-ID, MIME-Version, Content-*, DKIM-*, ARC-*, Authentication-Results, Received*, Resent-*, X-SES-*, List-Unsubscribe*, Auto-Submitted, and reply, receipt, trace and transport headers (Mail-Reply-To, Mail-Followup-To, Followup-To, Disposition-Notification-*, Return-Receipt-To, Errors-To, Bounces-To, Delivered-To, X-Original-To, DomainKey-*, Feedback-ID, TLS-Required, BIMI-*, Autocrypt*, OpenPGP). In-Reply-To and References must be <id@domain> Message-IDs and thread the message in the recipient's mail client. |
| `autoSubmitted` | string | no | Adds an RFC 3834 Auto-Submitted header so other automated systems do not reply to this message. |
| `addressId` | string | no | Opaque inbound address ID (mbx_…). |
| `replyToMessageId` | string | no | OpenSend message ID (msg_…) of a visible message in this thread. |
| `expectedRecipients` | object | no | Check the final To, Cc and Bcc against these reviewed address sets; never overrides recipients. A mismatch returns 409 INBOUND_RECIPIENTS_CHANGED. |
| `replyAll` | boolean | no | Also copy everyone else on the original message. |
| `to` | string[] | no | Override the computed recipients. |
| `cc` | string[] | no |  |
| `bcc` | string[] | no |  |
| `subject` | string | no | Defaults to "Re: <original subject>". |
| `quote` | boolean | no | Append the original message as quoted text. |
| `allowAutomated` | boolean | no | Reply even when the original is automated or the recipient is a no-reply address. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { replyToInboundThread } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await replyToInboundThread({
  client,
  path: {
    "threadId": "thread_123"
  },
  body: {
    "attachments": [],
    "replyTo": [],
    "headers": [],
    "replyAll": false,
    "bcc": [],
    "quote": false,
    "allowAutomated": false
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/threads/thread_123/reply' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "attachments": [],
  "replyTo": [],
  "headers": [],
  "replyAll": false,
  "bcc": [],
  "quote": false,
  "allowAutomated": false
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Queued, not yet delivered. | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound events

`GET /v1/inbound/events`

Use the returned cursor as after to continue polling. Workspace-wide message.stored events require admin access, no address filter, and an explicit message.stored type filter.

Operation ID: `listInboundEvents`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `after` | query | string | no | Cursor from a previous response. Omit to start at the current end of the log. |
| `wait` | query | integer or null | no | Seconds to wait for new events when none are ready (long-poll). |
| `types` | query | string | no | Comma-separated event types. |
| `limit` | query | integer | no |  |
| `addressId` | query | string | no | Include only this receiving address. |
| `addressIds` | query | string | no | Comma-separated receiving address IDs. Use instead of addressId. |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundEvents } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundEvents({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/events' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound keys

`GET /v1/inbound/keys`



Operation ID: `listInboundKeys`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `includeRevoked` | query | string | no |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundKeys } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundKeys({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/keys' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create inbound key

`POST /v1/inbound/keys`

Scope this credential to specific receiving addresses. If the filter is omitted it applies to every address, including future ones. The secret is returned once.

Operation ID: `createInboundKey`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |
| `permissions` | string[] | no |  |
| `addressIds` | string[] | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createInboundKey } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createInboundKey({
  client,
  body: {
    "name": "Example",
    "permissions": [
      "read",
      "send",
      "modify"
    ]
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/keys' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example",
  "permissions": [
    "read",
    "send",
    "modify"
  ]
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Revoke inbound key

`POST /v1/inbound/keys/{id}/revoke`



Operation ID: `revokeInboundKey`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revokeInboundKey } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await revokeInboundKey({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/keys/resource_123/revoke' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound webhooks

`GET /v1/inbound/webhooks`



Operation ID: `listInboundWebhooks`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundWebhooks } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundWebhooks({
  client,
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create inbound webhook

`POST /v1/inbound/webhooks`

Deliveries are signed with Standard Webhooks headers (Webhook-Id, Webhook-Timestamp, Webhook-Signature) and retried with backoff. The endpoint must be a public HTTPS URL. The signing secret is returned once.

Operation ID: `createInboundWebhook`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | yes |  |
| `description` | string | no |  |
| `eventTypes` | string[] | no |  |
| `paused` | boolean | no |  |
| `headers` | object[] | no | Write-only custom HTTP request headers, e.g. Authorization. Up to 10 unique names (case-insensitive) and 8192 UTF-8 bytes of names and values. Omit on update to keep, supply the complete list to replace, or [] to clear. Transport, Cookie and OpenSend delivery headers are reserved. |
| `addressIds` | array or null | no | Only events for these receiving addresses; null for all. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createInboundWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await createInboundWebhook({
  client,
  body: {
    "url": "https://example.com/webhook",
    "description": "",
    "eventTypes": [
      "message.received"
    ],
    "paused": false,
    "addressIds": null
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{
  "url": "https://example.com/webhook",
  "description": "",
  "eventTypes": [
    "message.received"
  ],
  "paused": false,
  "addressIds": null
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get inbound webhook

`GET /v1/inbound/webhooks/{id}`



Operation ID: `getInboundWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getInboundWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await getInboundWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update inbound webhook

`PATCH /v1/inbound/webhooks/{id}`



Operation ID: `updateInboundWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | no |  |
| `description` | string | no |  |
| `eventTypes` | string[] | no |  |
| `paused` | boolean | no |  |
| `headers` | object[] | no | Write-only custom HTTP request headers, e.g. Authorization. Up to 10 unique names (case-insensitive) and 8192 UTF-8 bytes of names and values. Omit on update to keep, supply the complete list to replace, or [] to clear. Transport, Cookie and OpenSend delivery headers are reserved. |
| `addressIds` | array or null | no | Only events for these receiving addresses; null for all. |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateInboundWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await updateInboundWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  body: {},
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY" \
  --header 'Content-Type: application/json' \
  --data '{}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete inbound webhook

`DELETE /v1/inbound/webhooks/{id}`



Operation ID: `deleteInboundWebhook`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteInboundWebhook } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await deleteInboundWebhook({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks/resource_123' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Rotate inbound webhook secret

`POST /v1/inbound/webhooks/{id}/rotate-secret`



Operation ID: `rotateInboundWebhookSecret`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { rotateInboundWebhookSecret } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await rotateInboundWebhookSecret({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks/resource_123/rotate-secret' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List inbound webhook deliveries

`GET /v1/inbound/webhooks/{id}/deliveries`



Operation ID: `listInboundWebhookDeliveries`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |
| `cursor` | query | string | no |  |
| `limit` | query | integer | no |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listInboundWebhookDeliveries } from 'opensend-js';

const client = createClient({
  baseUrl: 'https://opensend.anoma.ly',
  auth: scheme => scheme.scheme === 'bearer'
    ? process.env.OPENSEND_API_KEY
    : undefined,
});

const result = await listInboundWebhookDeliveries({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});

console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url 'https://opensend.anoma.ly/v1/inbound/webhooks/resource_123/deliveries' \
  --header "Authorization: Bearer $OPENSEND_API_KEY"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List workspaces

`GET /v1/workspaces`

Lists your memberships. Dashboard requests can select a membership with X-OpenSend-Workspace (workspace ID); without it, the most recent selection is used. Workspace administration requires a Google session.

Operation ID: `listWorkspaces`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listWorkspaces } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await listWorkspaces({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/workspaces" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create workspace

`POST /v1/workspaces`

Create another workspace you own, for example to keep separate products, teams or billing apart. It starts like a new signup: connect sending, then add a domain. Requires an account approved for sign-up; each account can own up to 10 workspaces. Select it with X-OpenSend-Workspace.

Operation ID: `createWorkspace`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createWorkspace } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await createWorkspace({
  client,
  body: {
    "name": "Example"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/workspaces" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Rename current workspace

`PATCH /v1/workspaces/current`



Operation ID: `renameCurrentWorkspace`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { renameCurrentWorkspace } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await renameCurrentWorkspace({
  client,
  body: {
    "name": "Example"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Example"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List workspace members

`GET /v1/workspaces/current/members`



Operation ID: `listWorkspaceMembers`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listWorkspaceMembers } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await listWorkspaceMembers({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/members" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Invite workspace member

`POST /v1/workspaces/current/members`

Invite an email address. Membership starts only after acceptance by the verified address. Share the returned URL; no email is sent.

Operation ID: `inviteWorkspaceMember`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | yes |  |
| `role` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { inviteWorkspaceMember } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await inviteWorkspaceMember({
  client,
  body: {
    "email": "recipient@example.com",
    "role": "owner"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/members" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "email": "recipient@example.com",
  "role": "owner"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List workspace invitations

`GET /v1/workspaces/current/invitations`

List pending, unexpired workspace invitations.

Operation ID: `listWorkspaceInvitations`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listWorkspaceInvitations } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await listWorkspaceInvitations({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/invitations" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create workspace invitation

`POST /v1/workspaces/current/invitations`

Invite an email address. Membership starts only after acceptance by the verified address. Share the returned URL; no email is sent.

Operation ID: `createWorkspaceInvitation`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `email` | string | yes |  |
| `role` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createWorkspaceInvitation } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await createWorkspaceInvitation({
  client,
  body: {
    "email": "recipient@example.com",
    "role": "owner"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/invitations" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "email": "recipient@example.com",
  "role": "owner"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Revoke workspace invitation

`DELETE /v1/workspaces/current/invitations`



Operation ID: `revokeWorkspaceInvitation`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | query | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { revokeWorkspaceInvitation } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await revokeWorkspaceInvitation({
  client,
  query: {
    "id": "resource_123"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/invitations?id=resource_123" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Update workspace member

`PATCH /v1/workspaces/current/members/{id}`



Operation ID: `updateWorkspaceMember`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |

### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `role` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { updateWorkspaceMember } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await updateWorkspaceMember({
  client,
  path: {
    "id": "resource_123"
  },
  body: {
    "role": "owner"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request PATCH \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/members/resource_123" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "role": "owner"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Remove workspace member

`DELETE /v1/workspaces/current/members/{id}`



Operation ID: `removeWorkspaceMember`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { removeWorkspaceMember } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await removeWorkspaceMember({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/current/members/resource_123" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Accept workspace invitation

`POST /v1/workspaces/invitations/{id}/accept`



Operation ID: `acceptWorkspaceInvitation`

### Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes |  |


### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { acceptWorkspaceInvitation } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await acceptWorkspaceInvitation({
  client,
  path: {
    "id": "resource_123"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/workspaces/invitations/resource_123/accept" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get connection

`GET /v1/connection`

Get the current MX workspace connection or null. Poll during BYO setup for awaiting_role, provisioning, ready or failed and the imported domain count. Owner/admin dashboard only.

Operation ID: `getConnection`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getConnection } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await getConnection({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/connection" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Create connection

`POST /v1/connection`

Choose a sending provider. Regional BYO enrollment requires an account ID and returns a role-only stack link and a read-only scan operation. Legacy enrollment and Hosted mail return 201.

Operation ID: `createConnection`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `kind` | string | yes |  |
| `region` | string | no |  |
| `awsAccountId` | string | no |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { createConnection } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await createConnection({
  client,
  body: {
    "kind": "shared"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/connection" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "kind": "shared"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `201` | Success | object |
| `202` | Success | value |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Delete connection

`DELETE /v1/connection`

Refuses outstanding mail and campaigns. Regional BYO fences sending and queues verified cleanup of its sending sets and feedback topic. Poll getConnection for the remaining manifest; repeat DELETE to resume after fixing access or drift. Keeps identities, DNS and mailbox data. Remove the customer role stack last. Legacy connections retain AWS resources.

Operation ID: `deleteConnection`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { deleteConnection } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await deleteConnection({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request DELETE \
  --url "${OPENSEND_ORIGIN}/v1/connection" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## List connection regions

`GET /v1/connection/regions`

Regions offered for shared sending, and the commercial AWS regions where Amazon SES supports sending for bring-your-own AWS. Owner/admin dashboard only.

Operation ID: `listConnectionRegions`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { listConnectionRegions } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await listConnectionRegions({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/connection/regions" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Refresh connection scan

`POST /v1/connection/scan`

Refresh regional inventory without changing AWS resources or selected domains.

Operation ID: `refreshConnectionScan`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { refreshConnectionScan } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await refreshConnectionScan({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/connection/scan" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Import connection domains

`POST /v1/connection/imports`

Select verified regional candidates explicitly. Sending requires confirmed regional feedback. Imported identities are never modified.

Operation ID: `importConnectionDomains`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `revision` | integer | yes |  |
| `candidateIds` | string[] | yes |  |
| `confirm` | boolean | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { importConnectionDomains } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await importConnectionDomains({
  client,
  body: {
    "revision": 1,
    "candidateIds": [
      "candidate_123"
    ],
    "confirm": true
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/connection/imports" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "revision": 1,
  "candidateIds": [
    "candidate_123"
  ],
  "confirm": true
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `202` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Get connection region status

`GET /v1/connection/regions/status`

Read regional AWS inventory, access, ownership journals and setup errors. Does not contact AWS.

Operation ID: `getConnectionRegionStatus`



### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { getConnectionRegionStatus } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await getConnectionRegionStatus({
  client,
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request GET \
  --url "${OPENSEND_ORIGIN}/v1/connection/regions/status" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR"
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |

---

## Verify connection

`POST /v1/connection/verify`

Manual fallback for automatic BYO stack detection. Prove the role and start verification and verified-domain import. Poll getConnection until ready. Safe to retry.

Operation ID: `verifyConnection`


### Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `awsAccountId` | string | yes |  |

### TypeScript SDK

```ts
import { createClient } from 'opensend-js/client';
import { verifyConnection } from 'opensend-js';

// Run in the signed-in dashboard, on its own origin.
const client = createClient({ baseUrl: window.location.origin, credentials: 'same-origin' });
const result = await verifyConnection({
  client,
  body: {
    "awsAccountId": "123456789012"
  },
  throwOnError: true,
});
console.log(result.data);
```

### cURL

```sh
curl --request POST \
  --url "${OPENSEND_ORIGIN}/v1/connection/verify" \
  --header "Origin: $OPENSEND_ORIGIN" \
  --cookie "$OPENSEND_COOKIE_JAR" \
  --header 'Content-Type: application/json' \
  --data '{
  "awsAccountId": "123456789012"
}'
```

### Responses

| Status | Description | Schema |
| --- | --- | --- |
| `200` | Success | object |
| `400` | Request failed; use error.code and requestId to diagnose. | object |
| `401` | Request failed; use error.code and requestId to diagnose. | object |
| `403` | Request failed; use error.code and requestId to diagnose. | object |
| `404` | Request failed; use error.code and requestId to diagnose. | object |
| `409` | Request failed; use error.code and requestId to diagnose. | object |
| `413` | Request failed; use error.code and requestId to diagnose. | object |
| `422` | Request failed; use error.code and requestId to diagnose. | object |
| `429` | Request failed; use error.code and requestId to diagnose. | object |
| `500` | Request failed; use error.code and requestId to diagnose. | object |
| `503` | Request failed; use error.code and requestId to diagnose. | object |
