# Scopes and permissions

> The four API key scopes (content, media, schedule, read), which endpoints each one unlocks, and which combination to give each kind of tool.

Source: https://docs.urnextdoor.com/getting-started/scopes/

Scopes decide what a key may do. You choose them when you [create the key](https://docs.urnextdoor.com/getting-started/create-api-key.md). Give each tool only the scopes it needs: if the key ever leaks, it can do less harm.

## The four scopes

| Scope | Allows | Endpoints |
| --- | --- | --- |
| `content` | Creating content, published now or scheduled | `POST /posts`, `/questions`, `/polls`, `/mcqs`, `/communities`, `/services`, `/jobs` |
| `media` | Uploading images | `POST /media` |
| `schedule` | Managing items you already scheduled | `GET /scheduled`, `POST /scheduled/{type}/{id}/reschedule`, `POST /scheduled/{type}/{id}/publish`, `DELETE /scheduled/{type}/{id}` |
| `read` | Lookups a tool needs to fill in ids | `GET /communities/postable`, `/service-categories`, `/job-options`, `/geo`, `/community-icons` |

Paths are relative to `https://urnextdoor.com/api/v1`.

Two endpoints need **no particular scope**, only a valid key: `GET /me` (who am I) and `GET /usage` (today's quota). `GET /openapi.json` is public and needs no key at all.

Scheduling a new item only needs `content`: add `scheduled_at` to the create. The `schedule` scope is for changing items after they are scheduled.

## Recommended combinations

| Tool | Scopes |
| --- | --- |
| AI agent that writes and publishes posts with images (Claude Code, Codex CLI) | `content`, `media`, `read` |
| The same agent, also allowed to move or cancel scheduled posts | `content`, `media`, `read`, `schedule` |
| ChatGPT custom GPT | `content`, `read` (add `media` only for very small images, see [ChatGPT Actions](https://docs.urnextdoor.com/ai/chatgpt-actions.md)) |
| Zapier or n8n flow that publishes from a spreadsheet | `content` (add `read` if it looks up communities) |
| A dashboard that only lists what is scheduled | `schedule` |
| Exploring the API in Postman | `read` first; add the others when you are ready to publish |

## When a scope is missing

The request answers `403` with the code `insufficient_scope` and names the missing scope:

```json
{
  "ok": false,
  "error": "This API key does not have the \"content\" scope. Create a key that includes it.",
  "code": "insufficient_scope",
  "request_id": "a1b2c3d4e5f60718"
}
```

You cannot add scopes to an existing key. Create a new key with the scopes you need, switch your tool to it, and revoke the old one.

## Scopes are not the only check

A scope says what kind of action a key may attempt. The API still checks your own permissions on every request, exactly as the website does. A key with `content` cannot post into a community where you are not an editor (or above): that answers `403 forbidden`. Use `GET /api/v1/communities/postable` to list the communities you can post in.

## Next steps

- [Create an API key](https://docs.urnextdoor.com/getting-started/create-api-key.md) with the right scopes.
- [Make your first request](https://docs.urnextdoor.com/getting-started/first-request.md).
- [Keep your API key safe](https://docs.urnextdoor.com/security.md).
