> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nylon.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Scope and safety

> What an agent's key reaches, what it cannot do, and how failures come back.

An agent calling Nylon publishes to real accounts belonging to real people. This page is what that is bounded by.

## Scope

<CardGroup cols={2}>
  <Card title="Your key, your reach" icon="key-round">
    The agent acts with a key you issued and can revoke. It reaches exactly the accounts that key reaches — the profiles on that Nylon organization, and nothing else.
  </Card>

  <Card title="No connecting on its own" icon="user-check">
    An account cannot be connected server-to-server. `create_connection` returns a URL a person has to open and approve, so an agent cannot add an account by itself.
  </Card>

  <Card title="Nothing hidden from you" icon="scroll-text">
    Every tool call is a line in your [request log](https://app.nylon.dev/logs), recorded as MCP, with the endpoint, the status and the profile it touched.
  </Card>

  <Card title="Revocable in one place" icon="ban">
    Deleting the key from the [API keys page](https://app.nylon.dev/api) ends the agent's access immediately. There is no separate grant to find.
  </Card>
</CardGroup>

<Note>
  Issue a separate key for agent use. One key per caller is what makes the log readable and the revocation cheap.
</Note>

## Why API keys and not OAuth

An OAuth grant would authorise an agent against your Nylon login — everything your account can do, including billing and team membership, mediated by a consent screen and a token you then have to manage separately.

A key is smaller. It is scoped to one organization, it is the credential your backend already holds, it appears in the same log as your backend's calls, and revoking it is a single delete. For a server whose whole job is "publish this", that is the right size of thing to hand to an agent.

The cost is that clients which only accept OAuth-authenticated remote servers need a [local bridge](/mcp/connect#clients-that-do-not).

## What cannot be undone

<Warning>
  Nothing published can be unpublished. `cancel_post` stops a post that has not sent yet; a post that has gone out stays out, and `retry_post` never re-sends a target that already published.
</Warning>

Two more asymmetries worth building around:

* **`update_post` replaces, it does not merge.** Sending `text` alone means that is the text now, and media or a link left out is cleared. An agent editing a scheduled post should read it with `get_post` first.
* **`retry_post` publishes immediately.** It republishes the targets that did not go out, now rather than at any scheduled time. A post that has not been attempted yet is refused with `conflict` — that would be sending it early, not retrying it — and a target that already published is never re-sent.

## How failures come back

The distinction matters for how an agent recovers, so the server draws it deliberately.

| Kind                        | Shape                                                                                               | What the agent should do                                                                                            |
| --------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| Nylon rejected the call     | A tool result with `isError: true`, carrying `{ "error": { "code", "message", "details" } }`        | Read the `code` and act on it — shorten the caption, pick a different profile, ask the user to reconnect an account |
| The call never got that far | A JSON-RPC error: `-32601` for an unknown tool, `-32602` for arguments that do not match the schema | Fix the call. This is a client problem, not an account problem                                                      |

Because the first kind is a *result* rather than a protocol error, the model sees the real sentence — `"LinkedIn allows at most 3000 characters"` — and can fix the post and try again. The [error taxonomy](/errors) is the same one the REST API uses; every code an endpoint can return, a tool can return.

<Note>
  A publish that fails **after** it started is not an error at all. The post is created, the tool returns successfully, and the per-target `status` and `error` say what each network did. Check the targets.
</Note>

## Rate limits

Tool calls spend the same per-key allowance as the REST API — 120 requests a minute for reads, 30 for publishing — so an agent gets one allowance, not a second helping alongside your backend. Protocol traffic (`initialize`, `tools/list`, `ping`) has a small bucket of its own so that discovering the tools never eats into publishing.

Exceeding either returns `rate_limited` with a `Retry-After`.

## Billing

Nothing changes. An agent's posts are your posts: the same profile allowance, the same subscription state. A profile beyond your allowance while billing is inactive comes back as `payment_required` through a tool exactly as it does through the API, with the message saying what to restart.
