# REST API

API keys, OAuth, least-privilege scopes, endpoints, errors, and lifecycle rules for Naasher API v1.

[العربية](/api)

Naasher's REST API is available on the **Teams** and **Agency** plans. Public SDK endpoints begin at `https://api.naasher.com/api/sdk/v1`; the interactive reference is available at [api.naasher.com/docs](https://api.naasher.com/docs), and the machine-readable contract is [OpenAPI 3.1](https://api.naasher.com/openapi.json).

## [Authentication](#authentication)

Create an API key under **Settings → Developers → API keys**, then send it in either supported header:

```
curl https://api.naasher.com/api/sdk/v1/posts \
  -H "x-naasher-api-key: $NAASHER_API_KEY"
```

```
curl https://api.naasher.com/api/sdk/v1/posts \
  -H "Authorization: Bearer $NAASHER_API_KEY"
```

A key is shown once

Naasher stores the key fingerprint, not a retrievable plaintext copy. Put the value in a secret manager. If it is lost or exposed, create a replacement, update the controlled caller, and revoke the old key.

### [OAuth 2.1 for agents and third-party applications](#oauth-21-for-agents-and-third-party-applications)

Use Authorization Code with PKCE (`S256`) when an application acts for a user. Discovery starts at:

```
https://api.naasher.com/.well-known/oauth-authorization-server
```

Register through the published `registration_endpoint`, send `resource=https://api.naasher.com/api/sdk/v1` in authorization and token requests, and request only required scopes. The user selects a workspace, and authorization remains bounded by that membership. Use refresh and revocation endpoints from discovery rather than sharing one long-lived key across customers.

## [Scopes](#scopes)

| Scope           | Capability                                                               |
| --------------- | ------------------------------------------------------------------------ |
| channels:read   | Read connected accounts                                                  |
| channels:update | Manage channel-related destination presets                               |
| posts:read      | Read posts                                                               |
| posts:create    | Create a draft or post record                                            |
| posts:update    | Update an existing post record                                           |
| posts:schedule  | Schedule an existing post                                                |
| posts:publish   | Publish or retry a post through its provider                             |
| posts:delete    | Delete a post record under the API contract                              |
| posts:share     | Create, list, or revoke post share links                                 |
| media:read      | List media records                                                       |
| media:upload    | Create an upload and confirm completion                                  |
| media:update    | Update media metadata                                                    |
| media:delete    | Delete a media record                                                    |
| schedule:read   | Read the calendar and schedule slots                                     |
| schedule:update | Create, update, or delete schedule slots                                 |
| analytics:read  | Read available analytics                                                 |
| webhooks:read   | Read webhook registrations                                               |
| webhooks:create | Create a webhook registration                                            |
| webhooks:delete | Delete a webhook registration                                            |
| \*              | True wildcard: satisfies every scope check, including scopes added later |

`*` is not shorthand for only the rows that existed when the key was created. The server treats it as a true wildcard and accepts every required permission. Avoid it unless the caller genuinely requires unrestricted API access. Start a new integration with read scopes, add each write scope separately, bind external actions to exact human authorization, and keep production and test credentials apart.

## [Endpoints](#endpoints)

### [Posts](#posts)

| Method | Path                | Purpose                                 |
| ------ | ------------------- | --------------------------------------- |
| GET    | /posts              | Cursor-paginated post list with filters |
| POST   | /posts              | Create a draft or scheduled post        |
| GET    | /posts/:id          | Read one post                           |
| POST   | /posts/:id/schedule | Schedule an existing post               |
| DELETE | /posts/:id          | Delete a post record                    |

Example scheduled post:

```
curl -X POST https://api.naasher.com/api/sdk/v1/posts \
  -H "x-naasher-api-key: $NAASHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "body": "We shipped the new release today.",
    "channelIds": ["ch_123"],
    "scheduledAt": "2026-09-03T06:00:00.000Z"
  }'
```

### [Channels, analytics, and webhooks](#channels-analytics-and-webhooks)

| Method | Path          | Purpose                               |
| ------ | ------------- | ------------------------------------- |
| GET    | /channels     | List connected accounts               |
| GET    | /channels/:id | Read one connected account            |
| GET    | /analytics    | Read the available analytics overview |
| GET    | /webhooks     | List webhook registrations            |
| POST   | /webhooks     | Register a webhook                    |
| DELETE | /webhooks/:id | Delete a webhook registration         |

See [Webhooks](/en/webhooks) before accepting event-driven writes.

## [Rate limits and errors](#rate-limits-and-errors)

Rate limiting applies per IP address and key. Read `RateLimit-Policy`, `RateLimit`, compatibility headers, and `Retry-After` rather than hard-coding a retry interval. Errors use a stable machine code inside a consistent envelope:

```
{ "error": { "code": "billing:feature_not_in_plan", "message": "API access is available on Teams and Agency." } }
```

Depend on `code`, not the human message. Do not automatically replay an uncertain create or schedule mutation until you have checked whether it already succeeded.

## [Versioning and deprecation](#versioning-and-deprecation)

`/api/sdk/v1` is the current stable major path. Compatible optional additions can land within v1; breaking changes require a new major version and an announced transition. Read [API lifecycle](/en/api-lifecycle) for `Deprecation`, `Sunset`, and minimum transition rules.

[Unified inbox and analyticsHandle supported conversations from one queue and report provider-supplied performance without inventing missing data.](/en/inbox-analytics)[Naasher API lifecycleVersioning, compatibility, deprecation, and sunset policy for the public Naasher API.](/en/api-lifecycle)

---

Canonical URL: https://docs.naasher.com/en/api
