Agents
Manage your AI agents from your app, ChatGPT or Claude — hire, change, pause, run, and approve what they make.
Nimply agents are AI helpers you hire from a gallery: a LinkedIn Ghostwriter, a Carousel Designer, a Trend Scout, a Customer Support agent and more. Each one does one job for your workspace, on the channels you give it.
With the API you can do what the Agents page in the app does:
- browse the gallery and hire an agent,
- change its settings, pause, resume or remove it,
- run it now and follow the run,
- approve what it made.
Agents never publish on their own. What a content agent makes lands as posts waiting for approval. Nothing goes out until someone approves it.
Scopes: agents:read to read, agents:write to hire, change and remove, agents:run to
start and cancel runs. All three are opt-in.
Two kinds of agent
Every template has a kind:
contentagents make posts, designs or idea cards when they run, by hand or on a schedule. Their output waits for approval.inboxagents answer conversations as messages arrive (for example Customer Support or Sales & Lead). You can hire, set up, pause and remove them through the API, but you can't run them by hand. The API never reads or sends inbox messages.
Endpoints
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /v1/agent-templates | agents:read | The agents you can hire, with the settings to fill |
GET | /v1/agent-templates/{id} | agents:read | One template |
GET | /v1/agents | agents:read | Your agents (status, templateId filters) |
POST | /v1/agents | agents:write | Hire an agent |
GET | /v1/agents/{id} | agents:read | One agent: settings, channels, status, schedule |
PATCH | /v1/agents/{id} | agents:write | Rename, change settings or channels, pause / resume |
DELETE | /v1/agents/{id} | agents:write | Remove an agent |
POST | /v1/agents/{id}/runs | agents:run | Run it now (uses AI credits) |
GET | /v1/agents/{id}/runs | agents:read | Recent runs, newest first (limit up to 50) |
GET | /v1/agent-runs/{id}?wait=0..25 | agents:read | One run (long-poll with wait) |
POST | /v1/agent-runs/{id}/cancel | agents:run | Stop a run |
Starting runs is limited to 10 requests per minute per key, on top of the general rate limit.
Browse the gallery
curl "https://api.nimply.io/v1/agent-templates" \
-H "Authorization: Bearer $NIMPLY_API_KEY"Each template lists the settings (fields) it needs. This one is trimmed to three fields:
{
"data": [
{
"id": "linkedin-ghostwriter",
"name": "LinkedIn Ghostwriter",
"description": "Builds your personal brand on LinkedIn — posts written in your voice from your notes, wins, and expertise, scheduled as drafts for your approval.",
"category": "LinkedIn",
"kind": "content",
"channelTypes": ["LINKEDIN_PROFILE", "LINKEDIN_PAGE"],
"multiChannel": false,
"presets": [],
"fields": [
{
"key": "voice",
"label": "Who are you on LinkedIn?",
"type": "text",
"required": true,
"askable": true,
"setupInApp": false
},
{
"key": "cadence",
"label": "Writing schedule",
"type": "choice",
"required": true,
"askable": true,
"setupInApp": false,
"options": [
{ "value": "weekly_monday", "label": "Weekly — Mondays 9:00 UTC" },
{ "value": "three_per_week", "label": "Mon / Wed / Fri — 9:00 UTC" },
{ "value": "weekdays", "label": "Every weekday — 9:00 UTC" },
{ "value": "manual", "label": "Only when I press Run" }
]
},
{
"key": "postCount",
"label": "Drafts per run",
"type": "choice",
"required": true,
"askable": true,
"setupInApp": false,
"options": [
{ "value": "1", "label": "1 post" },
{ "value": "2", "label": "2 posts" },
{ "value": "3", "label": "3 posts" }
]
}
],
"creditsPerRun": { "min": 2, "max": 12 }
}
]
}How to read a field:
| Property | Meaning |
|---|---|
type | channel (channel ids), choice (one of options, or a list when multiple), on/off (true/false), text, datetime (ISO 8601), or setup-page-only |
askable | true: you can set it through the API |
setupInApp | true: only the agent's setup page in the Nimply app can set it |
appOnlyValues | Option values you can only pick in the app (see Settings that stay in the app) |
onlyWhen | The field is used only while another field holds one of these values |
channelTypes lists the channels the agent works on (empty means any). presets are
ready-made versions of a template, such as the Designer's "Carousel Designer"; pass the
preset key when you hire. creditsPerRun is what one run usually uses.
Hire an agent
Send the template, the channel, and the settings you know. Channels go in channelIds, every
other setting goes in config.
curl -X POST "https://api.nimply.io/v1/agents" \
-H "Authorization: Bearer $NIMPLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "linkedin-ghostwriter",
"channelIds": ["5b8f1e2a-3c4d-4e6f-8a9b-0c1d2e3f4a5b"],
"config": {
"voice": "Founder of a specialty coffee roaster. Practical, warm, first person.",
"topics": "Sourcing stories, brewing tips, running a small business"
}
}'channelIds takes one channel, unless the template is multiChannel. name is optional
(it defaults to the template name and the channel), and so are preset and tags.
When settings are missing
If a required setting is missing, nothing is created. You get 422 with code
MISSING_FIELDS and a missingFields list. Ask the user for just those, then send the
same request again with them added.
{
"type": "https://developer.nimply.io/docs/errors#unprocessable-entity",
"title": "Unprocessable Entity",
"status": 422,
"detail": "LinkedIn Ghostwriter still needs: cadence (\"Writing schedule\", choice: weekly_monday | three_per_week | weekdays | manual); postCount (\"Drafts per run\", choice: 1 | 2 | 3). Ask the user for these and send them again (channels go in channelIds, everything else in config).",
"code": "MISSING_FIELDS",
"missingFields": [
{
"key": "cadence",
"label": "Writing schedule",
"type": "choice",
"options": [
{ "value": "weekly_monday", "label": "Weekly — Mondays 9:00 UTC" },
{ "value": "three_per_week", "label": "Mon / Wed / Fri — 9:00 UTC" },
{ "value": "weekdays", "label": "Every weekday — 9:00 UTC" },
{ "value": "manual", "label": "Only when I press Run" }
]
},
{
"key": "postCount",
"label": "Drafts per run",
"type": "choice",
"options": [
{ "value": "1", "label": "1 post" },
{ "value": "2", "label": "2 posts" },
{ "value": "3", "label": "3 posts" }
]
}
],
"instance": "/v1/agents"
}Once everything is there, you get 201 with the agent:
{
"id": "0d7c9e4b-2f1a-4b3c-9d8e-7f6a5b4c3d2e",
"name": "LinkedIn Ghostwriter — Brewhaus",
"templateId": "linkedin-ghostwriter",
"templateName": "LinkedIn Ghostwriter",
"kind": "content",
"status": "ACTIVE",
"pausedReason": null,
"channelIds": ["5b8f1e2a-3c4d-4e6f-8a9b-0c1d2e3f4a5b"],
"preset": null,
"config": {
"voice": "Founder of a specialty coffee roaster. Practical, warm, first person.",
"topics": "Sourcing stories, brewing tips, running a small business",
"cadence": "weekly_monday",
"postCount": "2"
},
"setInApp": [],
"schedule": { "cadence": "weekly_monday", "label": "Weekly — Mondays 9:00 UTC" },
"tags": [],
"createdAt": "2026-10-29T10:00:00.000Z",
"updatedAt": "2026-10-29T10:00:00.000Z",
"appUrl": "https://app.nimply.io/workspace/…/agents?instance=0d7c9e4b-…"
}schedulesays how often the agent runs on its own. It isnullwhen it only runs when asked. A scheduled run still sends its posts for approval.setInApplists settings that are set but can only be seen and changed in the app. Their values are not returned.appUrlopens the agent in the Nimply app (sign-in required).
Settings that stay in the app
Some settings let an agent act without a person checking first. You can only switch those on in the Nimply app, where the person can see what they agree to:
| Setting | Value only the app can pick | What it would do |
|---|---|---|
replyMode | auto | An inbox agent sends replies itself |
operatingMode | hybrid, autopilot | The Restaurant Concierge answers on its own |
mcpWriteMode | allow_changes | The agent changes data in your connected tools |
delivery | schedule | Posts are scheduled straight away, skipping approval |
Fields with setupInApp: true also stay in the app: uploads, connected tools, Google Sheets
and other custom editors.
Sending one of these returns 422 with code SET_IN_APP. The problem body names the
settings in fields and gives appUrl, the link to the agent's setup page. Show that link
to the user so they can finish there.
{
"type": "https://developer.nimply.io/docs/errors#unprocessable-entity",
"title": "Unprocessable Entity",
"status": 422,
"detail": "These settings can only be chosen in the Nimply app: Reply mode. Open https://app.nimply.io/workspace/…/agents/setup/customer-support to set them there.",
"code": "SET_IN_APP",
"fields": ["Reply mode"],
"appUrl": "https://app.nimply.io/workspace/…/agents/setup/customer-support",
"instance": "/v1/agents"
}Change, pause, resume, remove
PATCH /v1/agents/{id} changes only what you send:
configis merged into the current settings.nullclears one setting. Settings you don't send are kept, including ones set in the app.channelIdsreplaces the agent's channels.nameandtagsreplace theirs.statuspauses (PAUSED) or resumes (ACTIVE) the agent.
curl -X PATCH "https://api.nimply.io/v1/agents/0d7c9e4b-2f1a-4b3c-9d8e-7f6a5b4c3d2e" \
-H "Authorization: Bearer $NIMPLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "config": { "postCount": "3" }, "status": "PAUSED" }'Pausing an agent also pauses the automations that work with it. Resuming does not switch
those automations back on: turn them on again with
POST /v1/automations/{id}/activate.
DELETE /v1/agents/{id} removes the agent. Posts it already made are kept. Automations that
worked with it are kept and paused.
pausedReason tells you when Nimply paused an agent itself, for example CHANNEL_REMOVED
after its channel was disconnected.
Run an agent
curl -X POST "https://api.nimply.io/v1/agents/0d7c9e4b-2f1a-4b3c-9d8e-7f6a5b4c3d2e/runs" \
-H "Authorization: Bearer $NIMPLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'Some templates take an optional input, such as a topic or a source link:
{ "input": { "topic": "Our new single-origin from Ethiopia" } }.
Plans and credits: running agents needs a paid plan or an active trial. A run uses AI
credits from your workspace. When it starts, Nimply holds the most it is expected to use
(creditsLocked). When it ends, you pay only what it used (creditsUsed). If the workspace
is short of credits, the run is refused with 402 and code INSUFFICIENT_CREDITS. Your plan
also sets how many runs you get each month.
The answer is 202 with the run. Runs are asynchronous: poll
GET /v1/agent-runs/{id}?wait=25. With wait, the request is held for up to 25 seconds and
returns as soon as the run changes.
{
"id": "7a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d",
"agentId": "0d7c9e4b-2f1a-4b3c-9d8e-7f6a5b4c3d2e",
"status": "COMPLETED",
"trigger": "MANUAL",
"creditsLocked": 12,
"creditsUsed": 6,
"error": null,
"startedAt": "2026-10-29T10:05:02.000Z",
"completedAt": "2026-10-29T10:05:48.000Z",
"createdAt": "2026-10-29T10:05:00.000Z",
"outputs": {
"postIds": ["c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f", "d4e5f6a7-b8c9-4d0e-9f1a-2b3c4d5e6f7a"]
}
}status moves from PENDING to PROCESSING, then ends as COMPLETED, FAILED or
CANCELLED. outputs lists what the run made: postIds, and when there are any, designIds
and ideaIds (idea cards).
POST /v1/agent-runs/{id}/cancel stops a run. A queued run stops at once and its held
credits are given back. A running one stops at its next checkpoint, and the work already done
is charged. A finished run is returned unchanged.
Approve what the agent made
The posts in outputs.postIds wait in the Planner with status PENDING_APPROVAL. Look at them
with GET /v1/posts/{id}, then approve or reject:
curl -X POST "https://api.nimply.io/v1/posts/c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f/approve" \
-H "Authorization: Bearer $NIMPLY_API_KEY"Approving needs the posts:write and posts:publish scopes. An approved post with a future
publish time goes back on the schedule; one without becomes a draft. Use
POST /v1/posts/{id}/reject to send it back. Your team also sees these posts in the app and
can approve them there.
Who can do what
Keys act for a person: the user who approved the connection (OAuth), or the person who made the API key. That person's workspace role decides what the call may do:
| Action | Roles |
|---|---|
| Read templates, agents and runs | Any member |
| Hire, change, pause, resume, run, cancel a run | Owner, admin, editor |
| Remove an agent | Owner, admin |
Otherwise the call fails with 403 and code INSUFFICIENT_ROLE.
Errors
| Status | code | Meaning |
|---|---|---|
400 | INVALID_CONFIG | An unknown setting or preset, a value the field doesn't take, or a channel the agent can't use |
402 | INSUFFICIENT_CREDITS | Not enough AI credits to start the run; the body has needed and available |
403 | AGENT_QUOTA_EXCEEDED | Your plan allows no more agents |
403 | AGENT_RUN_QUOTA_EXCEEDED | This month's agent runs are used up |
403 | PAID_PLAN_REQUIRED | Running agents needs a paid plan or an active trial |
403 | INSUFFICIENT_ROLE | The person the key acts for needs a higher workspace role |
403 | — | The key or connection is missing an agents:* scope |
409 | AGENT_PAUSED | Resume the agent before running it |
422 | MISSING_FIELDS | Required settings are missing; see missingFields |
422 | SET_IN_APP | A setting only the Nimply app can choose; see fields and appUrl |
422 | AGENT_RUNS_FROM_INBOX | Inbox agents answer messages as they arrive and can't be run by hand |
429 | — | Too many requests, or too many runs at once; retry after Retry-After seconds |
From ChatGPT, Claude and other assistants
The MCP server (version 0.7.0 and later) has matching tools: list_agent_templates,
list_agents, get_agent, hire_agent, update_agent, set_agent_status, remove_agent,
run_agent, get_agent_run and cancel_agent_run. Ask things like:
- "Hire a LinkedIn ghostwriter for my page." The assistant asks only for the settings Nimply still needs.
- "Pause my Trend Scout."
- "Run my ghostwriter now and show me the drafts." The assistant shows the posts and approves them only when you say so.
Connections made before these tools existed don't have agent access yet. Reconnect Nimply in your assistant and approve the agent permissions.
Set up a brand kit and teach it your look
Create a brand kit, fill it from your website, a PDF brand book, text, a channel or images, and teach it how your designs look — from the API, ChatGPT, Claude or any MCP client.
Automations
Build automations from your app, ChatGPT or Claude — start from a recipe or a list of steps, test, then switch on.