Skip to content

The API does for an app what the dashboard does: it installs or creates the agent, creates the project with its publishable key, posts the app’s pages to the page catalog, and drafts journeys. A coding agent connected to Super Assist’s MCP server calls it as you. Without the MCP server, you or the agent call it with an organization key and curl, from the app’s repository.

The commands call https://superassist.app. When the app’s runtime sets host to another Super Assist origin, call that origin instead. The API reference lists every route and field.

The MCP server at https://superassist.app/mcp lets a coding agent call the API as you, in the organization you picked when you signed in. Connect a coding agent installs it with the Super Assist plugin in Claude Code, or adds it by URL in Codex, Cursor and VS Code. The Super Assist skill’s setup and sync commands then run this page’s steps for you.

The server has two tools:

  • search looks up a route’s parameters, body and answer in the API’s description.
  • execute runs the agent’s code in a sandbox whose request({ method, path, query, body }) calls a /api/v1 route and returns its JSON answer. A refused call throws an error naming the method, path and status, with the API’s code, message and details.

The code is an async arrow function that returns its result, calling codemode.request(). One execute that lists the projects and reads the first one’s page catalog:

async () => {
const { data } = await codemode.request({ method: "GET", path: "/api/v1/projects" });
return codemode.request({ method: "GET", path: `/api/v1/projects/${data[0].id}/pages` });
};

The routes, bodies and answers are the ones below. Each execute can make several calls, and Claude Code shows its code before it runs. The organization key and the curl commands are the way in for an agent without the MCP server, or for you in a terminal.

An organization key calls the API as your organization. Only owners and admins see the API keys page that creates one.

  1. In the dashboard, open API keys, name the key, for example Coding agent, and press Create key.

  2. Copy the key. It starts with sa_, and the page shows it only once.

  3. Add it to .env.local in the app’s repository, without quotes:

    .env.local
    SUPER_ASSIST_API_KEY=sa_...
  4. Check that git ignores the file:

    Terminal window
    git check-ignore .env.local

    It prints .env.local when the file is ignored. When it prints nothing, add .env.local to .gitignore before you go on.

Each command reads the key from .env.local and sends it as a bearer token, so the key stays out of your code, your shell history and the command’s output:

Terminal window
key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
curl -s "https://superassist.app/api/v1/agents?limit=100" -H "Authorization: Bearer $key"

Keep -v off: it prints the Authorization header. A refused call answers with an error code and a message, such as:

{
"error": {
"code": "agent_name_taken",
"message": "An agent named \"saas-support\" already exists"
}
}

unauthorized means the key is wrong or was revoked. A long JSON body is easier to write to a file and send with --data-binary @file.json.

The project needs an agent to answer. Reuse one, install a template, or create one, in that order:

  1. List the organization’s agents with the command above. The answer is { "data": [...], "nextCursor": null }, each agent with its id and name. When one is named after the app, keep its id and go on to Create the project.

  2. Otherwise, list the templates and install the one that fits the app. A template’s id is its name:

    Terminal window
    key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
    curl -s https://superassist.app/api/v1/templates -H "Authorization: Bearer $key"
    Terminal window
    key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
    curl -s -X POST https://superassist.app/api/v1/templates/saas-support/install \
    -H "Authorization: Bearer $key"

    The install answers 201 with the agent, named after the template. It creates the template’s skills and databases too, reusing any skill your organization already has by name. An agent or database of the same name answers 409, and a plan limit 402.

  3. Otherwise, create an agent. Its name takes lowercase letters, numbers and single hyphens:

    Terminal window
    key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
    curl -s -X POST https://superassist.app/api/v1/agents \
    -H "Authorization: Bearer $key" -H "Content-Type: application/json" \
    -d '{"name":"my-shop","description":"Helps the shop team with orders and customers.","instructions":"You help the team of My shop work through their orders and customers on the open page."}'

    It answers 201 with the agent, on the default model.

An installed template’s skills carry bracketed placeholders, such as [billing page], listed under the template’s placeholders in the templates answer. Templates says what each of saas-support’s stands for.

  1. List the skills with GET /api/v1/skills?limit=100, and find each placeholder in their instructions.

  2. Replace it with what the app’s repository says, and send the skill’s whole instructions back:

    Terminal window
    key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
    curl -s -X PATCH https://superassist.app/api/v1/skills/<skill-id> \
    -H "Authorization: Bearer $key" -H "Content-Type: application/json" \
    --data-binary @skill.json

    Here skill.json holds { "instructions": "..." }.

  3. Save the agent with an empty body, so its threads pick up the edited skills:

    Terminal window
    key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
    curl -s -X PATCH https://superassist.app/api/v1/agents/<agent-id> \
    -H "Authorization: Bearer $key" -H "Content-Type: application/json" -d '{}'

Leave a placeholder the repository doesn’t answer, and note it for whoever finishes in the dashboard.

Create the project with the agent as its default and the origins the app runs on in development:

Terminal window
key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
curl -s -X POST https://superassist.app/api/v1/projects \
-H "Authorization: Bearer $key" -H "Content-Type: application/json" \
-d '{"name":"My shop","defaultAgentId":"<agent-id>","allowedOrigins":["http://localhost:3000"]}'

allowedOrigins replaces the default list, so name every origin. Left out, the project allows http://localhost:3000 and http://localhost:5173. The answer is 201 with the project:

{
"id": "7c1e4b0a-…",
"name": "My shop",
"description": null,
"publishableKey": "pk_…",
"allowedOrigins": ["http://localhost:3000"],
"defaultAgentId": "<agent-id>",
"createdBy": null,
"createdAt": "2026-11-01T10:00:00.000Z",
"updatedAt": "2026-11-01T10:00:00.000Z"
}

Write publishableKey to the app’s public variable in .env.local, such as NEXT_PUBLIC_SUPER_ASSIST_KEY for Next.js or VITE_SUPER_ASSIST_KEY for Vite. Unlike the organization key, it ships in the app’s bundle. Use the hosted runtime connects the app with it.

When the app already has a project, find its id in GET /api/v1/projects, by the publishableKey the app uses.

The page catalog holds the app’s pages for the journey editor’s pickers. Pages report themselves once the app runs; posting them now puts the whole sitemap in the catalog from the start. Send one entry per destinations path, with the page’s name, its instructions, and the actions and fields it lends:

Terminal window
key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
curl -s -X POST https://superassist.app/api/v1/projects/<project-id>/pages \
-H "Authorization: Bearer $key" -H "Content-Type: application/json" \
--data-binary @pages.json
pages.json
{
"pages": [
{
"path": "/orders",
"name": "Orders",
"instructions": "Every order of the shop. Ship or cancel an order that is waiting to ship by its id.",
"elements": [
{ "name": "new_order", "kind": "action", "label": "Open the New order dialog" },
{ "name": "ship_order", "kind": "action", "byId": true }
]
},
{
"path": "/orders/:id",
"name": "Order",
"elements": [
{ "name": "note", "kind": "field", "label": "The order's note" },
{ "name": "save_note", "kind": "action", "label": "Save the note" }
]
}
]
}
  • byId: true marks a name that rows lend, each with its own id. It keeps no label.
  • A page sent without instructions keeps those it has.
  • One request takes 1 to 100 pages and at most 2,000 elements.

The answer is the whole catalog, { "data": [...] }, and the project’s Pages tab shows it.

A post only adds and updates. Once the app’s routes change, add "replace": true beside pages and send every page the code has: the catalog then keeps only what you sent. The Super Assist skill’s sync command builds that body from the code and sends it. Pages you left out go with their elements, those the app reported itself included, and so do the elements a page you sent leaves out. When a page you dropped by mistake still lends something, the app reports it back the next time an end user opens it.

A journey walks end users through the app toward a goal, one step at a time. Start with up to three, each of three or four steps, built from the app’s routes and what its pages lend:

Terminal window
key=$(sed -n 's/^SUPER_ASSIST_API_KEY=//p' .env.local)
curl -s -X POST https://superassist.app/api/v1/projects/<project-id>/journeys \
-H "Authorization: Bearer $key" -H "Content-Type: application/json" \
--data-binary @journey.json
journey.json
{
"name": "ship-an-order",
"goal": "A new team member ships an order and leaves a note on it.",
"trigger": "manual",
"steps": [
{
"path": "/orders",
"title": "Your orders",
"body": "Every order of the shop is listed here."
},
{
"path": "/orders",
"element": { "kind": "action", "name": "ship_order" },
"title": "Ship an order",
"body": "Press Ship on an order that is waiting to ship."
},
{
"path": "/orders/:id",
"element": { "kind": "field", "name": "note" },
"title": "Leave a note",
"body": "Each order keeps a note for your team."
},
{
"path": "/orders/:id",
"element": { "kind": "action", "name": "save_note" },
"title": "Save it"
}
]
}
  • name follows the same rule as an agent’s and is unique in the project.
  • A step’s path is a destinations path, and its optional element is an action or field that page lends, by its lent name. The API doesn’t check either against the catalog, so take them from the pages you posted.
  • A journey has 1 to 10 steps. A title takes up to 120 characters, a body up to 1,000.
  • manual starts the journey only from host code or a link. page starts it once per end user on its first step’s page. A member can change it before publishing.

The answer is 201 with the journey, its state draft and its publishedSteps null: end users see nothing of it yet. A name already taken answers 409 journey_name_taken. To change a draft, send the changed fields to PATCH /api/v1/projects/<project-id>/journeys/<journey-id>.

Only a member publishes a journey. A coding agent on the MCP server acts as you, so it can publish a draft once you say so, with POST /api/v1/projects/<project-id>/journeys/<journey-id>/publish. The same route answers an organization key with 403: on the project’s Journeys page, set each draft’s trigger and publish it.

The key stays in .env.local for later drafts. When you no longer need it, press Revoke beside it on API keys.