evyAI API
The evyAI API lets a script, a tool or an AI agent act on one user’s evyAI account with a personal access token: read and write connections, notes, to-dos, personas, styles, assets and Agent memory, generate content and images in that user’s voice, create campaign drafts, publish to LinkedIn, and email the user. It shipped in October 2026 under API and MCP in Settings.
If you want Claude to use evyAI rather than writing code, you want the MCP connector instead. Same tools, no code.
Get a token
Section titled “Get a token”- Sign in to evyAI and open Settings > API and MCP (direct link).
- Click New token, tick the permissions it may use, and pick a lifetime (default 90 days).
- Copy it. The token is shown once.
Send it on every call:
Authorization: Bearer <your token>A token acts as the user who made it, limited to the permissions it was given. There is no organization-level key. Revoke a token from the same Settings page.
Shape of the API
Section titled “Shape of the API”The API is RPC-style, not REST. Every operation is a POST to the capability’s name with a JSON body:
POST https://services.api.evyai.com/api/capabilities/<capability.name>Content-Type: application/json
{ ...input }GET https://services.api.evyai.com/api/capabilitiesreturns the catalog: every capability’sname,description,scope(the permission it needs),effect(read,writeorspend) and itsinputJSON Schema. An agent should call this first and discover the rest. It is the only GET.- An OpenAPI 3.1 spec is public at
https://services.api.evyai.com/api/capabilities/openapi.json(no token needed). - Success:
{"success": true, "data": {...}}. Failure:{"success": false, "errorId": N, "message": "..."}. - Lists come back as
{"total": N, "<plural>": [...]}. Every object carries itsidand a deep-linkurlinto the app. - Dates are
yyyy-MM-dd. Times are wall-clock in thetimezoneyou send (an IANA name such asAmerica/New_York).
Capabilities
Section titled “Capabilities”37 capabilities, named <area>.<verb>:
| Area | Capabilities | Effect |
|---|---|---|
| Profile and brand | profile.get, profile.update, brand.get, socialCard.get | read, write |
| Content | content.generate (post, ideas, comment, message and more, in the user’s voice) | spend |
| Images | image.generate (can use the user’s photos and logo) | spend |
email.sendToMe (only to the account’s own address) | write | |
| Connections | connections.find, connections.get, connections.create, connections.update, connections.addToList, notes.add | read, write |
| To-dos | todos.list, todos.add, todos.update, todos.complete, todos.delete | read, write |
| Campaigns | campaigns.list, campaigns.createDraft, campaigns.createManual, campaigns.addPosts | read, write |
linkedin.publish (now or scheduled; needs LinkedIn connected in evyAI) | write | |
| Personas and styles | personas.list, personas.create, personas.update, styles.list, styles.create, styles.update | read, write |
| Assets | assets.list, assets.get, assets.create, assets.update | read, write |
| Agent memory | memory.list, memory.add, memory.update, memory.delete | read, write |
Prospect search, profile preview and unlocking people are available through the MCP connector and are not in the REST catalog at the time of writing.
Permissions
Section titled “Permissions”Each token carries the permissions you ticked. A call without the needed
permission returns 403 and names the permission in message.
| Permission | Covers |
|---|---|
| Read / change your own profile | profile.*, brand.get |
| Read your social card | socialCard.get |
| Read / add and change connections, notes and to-dos | connections.*, notes.add, todos.* |
| Write posts and other content (can cost coins) | content.generate, image.generate |
| Read / create campaigns | campaigns.* |
| Publish and schedule posts on your LinkedIn | linkedin.publish |
| Email things to your own address | email.sendToMe |
| Personas and writing styles | personas.*, styles.* |
| Assets | assets.* |
| What the Agent remembers about you | memory.* |
What it costs
Section titled “What it costs”| Effect | Capabilities | Charge |
|---|---|---|
| read | every *.get, *.list, *.find | free |
| write | create, update, add, complete, delete, email, campaigns, publish | free |
| spend | content.generate, image.generate | the same as the action in the app: 1 evyCoin minimum per text generation (more for longer output) and 5 evyCoins per image on the free plan; text is unlimited on Premium and Pro |
Nothing else is metered. See evyCoins.
Rate limit
Section titled “Rate limit”300 calls per minute per user, announced in standard IETF headers on every response:
ratelimit: "300-in-1min"; r=297; t=15ratelimit-policy: "300-in-1min"; q=300; w=60r is calls remaining, t is seconds until reset. Over the limit returns
HTTP 429. Read r and back off instead of retry-looping.
Errors
Section titled “Errors”| HTTP | When |
|---|---|
| 400 | input fails validation (required field missing, value out of range) |
| 401 | missing, invalid, expired or revoked token |
| 403 | token lacks the permission; message names it |
| 404 | unknown capability, or an id that is not in this account |
| 409 | already exists (for example a duplicate LinkedIn URL on connections.create) or the memory is full |
| 429 | rate limit; wait a minute |
| 500 | the server could not finish; also returned for malformed JSON bodies |
Gotchas we measured
Section titled “Gotchas we measured”- Unknown fields are silently ignored. The schemas say
additionalProperties: false, but a misspelled field name does not error, it just does nothing. Required and range checks do fire. - No pagination.
connections.findreturns at most 20 results and ignoresoffset. With a search term,totalalso tops out at 20. Narrow the search instead of paging. Other lists return up to 20 as well. connections.finddoes not search LinkedIn URLs. It matches name, company, headline, email and phone. Search the person’s name.- Always send
timezone. Leave it out and times are read as UTC. image.generatereturns a signed URL that expires in one hour. Download it right away. The image stays in the user’s in-app history.content.generatewithkind: "ideas"returns one string holding all the ideas, not one element per idea. Split it yourself.- No delete for most records. Connections, notes, personas, styles, assets and campaigns can be created and updated but not deleted through the API. Only to-dos and memories have a delete. Test writes leave real records; exercise the write path with a memory add, update and delete.
linkedin.publishis irreversible. Givedateandtimeto schedule, omit both to post now. It fails with a pointer to Settings if no LinkedIn account is connected.- Campaigns are called workflows in parts of the response. Draft campaigns created through the API are reviewed and launched in the app.
- Memory entries are 250 characters and the same ones the in-app Agent reads. What you write here changes how evyAI writes for that user.
Example
Section titled “Example”Read the user’s profile, then write a post in their voice:
curl -s -X POST https://services.api.evyai.com/api/capabilities/profile.get \ -H "Authorization: Bearer $EVYAI_TOKEN" \ -H "Content-Type: application/json" -d '{}'
curl -s -X POST https://services.api.evyai.com/api/capabilities/content.generate \ -H "Authorization: Bearer $EVYAI_TOKEN" \ -H "Content-Type: application/json" \ -d '{"kind":"post","instructions":"Why follow up beats cold outreach. Include one story from my own experience and end with a question."}'Check the input schema in the catalog for the exact fields each capability
accepts; the catalog is the source of truth and may grow.
Related
Section titled “Related”- Connect evyAI to Claude (MCP)
- MCP connector for builders
- Chat URL API for deep links that open the Agent with a question