andibase

Get started (for AI Agents)

Open Markdown

andibase

Build and operate AI-native workflows with one shared system for AI agents & humans.

Skill Files

FileURL
SKILL.md (this file)https://andibase.com/skill.md
Docs.mdhttps://andibase.com/docs.md
Recipeshttps://andibase.com/docs/receipes

Install locally:

mkdir -p ~/.agents/skills/andibase
curl -s https://andibase.com/skill.md > ~/.agents/skills/andibase/SKILL.md

Or just read them from the URLs above!

For inspiration before you build:

Use these recipes when you want a starting point for a new agent, app, or workflow.

Base URL: https://andibase.com/api/v1/

What this login flow gives you

This flow gives an agent a reusable workspace API key for the regular HTTP API.

It does not return an OAuth token, and it is not the MCP OAuth flow.

If you complete this flow successfully, save apiKey.key and use it in:

Authorization: Bearer <api-key>

for future /api/v1/... requests.

Login first

Every agent needs to start login and get approved by their human:

curl -X POST https://andibase.com/api/v1/agent/auth/requests \
  -H "Content-Type: application/json" \
  -d '{
    "agentName": "YourAgentName",
    "agentDescription": "What your agent does",
    "role": "admin"
  }'

If you omit role, the API defaults to admin.

Response:

{
  "deviceCode": "dc_xxx",
  "userCode": "ABCD-1234",
  "verificationUri": "https://andibase.com/agent-login",
  "verificationUriComplete": "https://andibase.com/agent-login?user_code=ABCD-1234",
  "expiresAt": "2026-03-07T18:15:00.000Z",
  "intervalSeconds": 5,
  "instructions": {
    "verificationMessage": "Ask the user to open verificationUriComplete and approve the request.",
    "exchangeMessage": "After approval, call POST /api/v1/agent/auth/exchange with deviceCode.",
    "apiKeySecretField": "apiKey.key",
    "apiKeySaveHint": "When exchange succeeds, save apiKey.key immediately. The secret is returned once and should be reused for future calls."
  }
}

The only two fields the agent must keep are:

  • verificationUriComplete: send this to the human
  • deviceCode: use this for polling and exchange

Agent flow in 4 steps

  1. Call POST /api/v1/agent/auth/requests.
  2. Show the human verificationUriComplete.
  3. Poll POST /api/v1/agent/auth/exchange with deviceCode.
  4. Save apiKey.key and reuse it for future HTTP API calls.

Exchange device code

Call this endpoint until you get either:

  • success with apiKey.key, or
  • a terminal error such as access_denied, expired_token, or invalid_grant
curl -X POST https://andibase.com/api/v1/agent/auth/exchange \
  -H "Content-Type: application/json" \
  -d '{"deviceCode":"dc_xxx"}'

What exchange means here

This endpoint is named exchange, but the important behavior is:

  • while approval is still pending, it tells the agent to wait,
  • once approved, it issues a reusable API key,
  • the secret is returned at apiKey.key exactly once.

Response: pending

{
  "code": "authorization_pending",
  "message": "The customer has not approved this login request yet."
}

Response: slow down

{
  "code": "slow_down",
  "message": "Poll less frequently and retry in about 5 seconds."
}

Response: success

{
  "status": "approved",
  "workspace": {
    "handle": "acme-growth-team",
    "name": "Acme Growth Team",
    "createdAt": "2026-03-05T18:00:00.000Z",
    "updatedAt": "2026-03-05T18:00:00.000Z",
    "deletedAt": null
  },
  "apiKey": {
    "key": "andi_live_xxx",
    "apiKey": {
      "id": "key_6ZW0qF8cXTWETrdFM3A7yv",
      "name": "Claude production key",
      "start": "andi_l",
      "prefix": "andi_",
      "enabled": true,
      "role": "admin",
      "createdAt": "2026-03-07T18:10:00.000Z",
      "updatedAt": "2026-03-07T18:10:00.000Z",
      "expiresAt": null,
      "lastRequest": null
    }
  },
  "usage": {
    "saveHint": "Store this API key in a secrets manager or environment variable before continuing. Reuse the same key for future calls instead of re-running login. The secret is only returned once.",
    "recommendedEnvVar": "ANDI_API_KEY",
    "authorizationHeader": "Authorization: Bearer <api-key>",
    "secretField": "apiKey.key",
    "lifecycle": "This key is persistent until revoked or until its configured expiration, if any."
  }
}

What to do for each response

ResponseMeaningAgent action
authorization_pendingThe human has not approved yetSleep and poll again
slow_downYou are polling too quicklyWait longer, then retry
access_deniedThe human rejected the requestStop and ask for a new login
expired_tokenThe login request expiredStart a new login
invalid_grantThe deviceCode is invalid, already consumed, or no longer usableStart a new login
successThe request was approved and the key was issuedSave apiKey.key immediately

Minimal polling loop

while (true) {
  const response = await fetch("https://andibase.com/api/v1/agent/auth/exchange", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ deviceCode }),
  });

  const payload = await response.json();

  if (response.ok) {
    const apiKey = payload.apiKey.key;
    // Save securely and reuse for future HTTP API calls.
    break;
  }

  if (payload.code === "authorization_pending") {
    await sleep(5000);
    continue;
  }

  if (payload.code === "slow_down") {
    await sleep(7000);
    continue;
  }

  throw new Error(`Agent login failed: ${payload.code}`);
}

Important: save apiKey.key immediately. You need it for all authenticated HTTP API requests after approval.

Recommended: Save credentials to ~/.config/andibase/credentials.json:

{
  "api_key": "andi_live_xxx",
  "agent_name": "YourAgentName"
}

Use the key after exchange

After exchange succeeds, use the key in the regular HTTP API:

curl "https://andibase.com/api/v1/data-definitions" \
  -H "Authorization: Bearer andi_live_xxx"

You do not need to run login again for every task. Reuse the same key until it is revoked or expires.

Create and edit apps

Agents can create workspace apps and revise them later through the apps API.

  • POST /api/v1/apps creates a new app.
  • PATCH /api/v1/apps/:handle updates an existing app.
  • GET /api/v1/apps/:id returns the full saved app, including code.

Each app stores a code field. That field must be a complete single JSX module that exports a default React component.

When the user asks to improve an existing app, start from the current saved app instead of rewriting it from scratch.

  • Fetch the current app first and use its saved code as the base for edits.
  • Preserve the existing design language, layout, spacing, and interaction patterns unless the user explicitly asks for a redesign.
  • Prefer small, targeted changes over broad rewrites.
curl -X POST https://andibase.com/api/v1/apps \
  -H "Authorization: Bearer andi_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Expense Tracker",
    "handle": "expense-tracker",
    "description": "Track workspace expenses",
    "code": "import { Button } from \"@andibase/ui/button\";\n\nexport default function App() {\n  return <main style={{ padding: 24 }}><h1>Expense Tracker</h1><Button>Add expense</Button></main>;\n}"
  }'

To revise an app, send the updated fields and replace code with the full next version of the module:

curl -X PATCH https://andibase.com/api/v1/apps/expense-tracker \
  -H "Authorization: Bearer andi_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Track and review workspace expenses",
    "code": "import { Button } from \"@andibase/ui/button\";\n\nexport default function App() {\n  return <main style={{ padding: 24 }}><h1>Expense Tracker</h1><Button>New report</Button></main>;\n}"
  }'

App runtime

Apps render at /w/:handle/apps/:handle inside a sandboxed iframe for signed-in workspace members.

  • Use window.andibase.fetch(path, init?) inside app code to call the API from the app runtime.
  • That helper sends credentials: "include" and adds the workspace handle automatically.
  • Do not hardcode bearer tokens inside app source.

The embedded app runtime has access to shared UI components from @andibase/ui.

  • You can import from @andibase/ui and subpaths like @andibase/ui/button, @andibase/ui/input, and similar shared components.
  • Prefer those shared components when building or editing apps in this runtime.
  • Use the existing @andibase/ui primitives as much as possible before reaching for custom CSS or Tailwind.
  • Keep the default shadcn/ui styling unless custom layout or behavior is strictly necessary.

@andibase/ui packages shared shadcn/ui components for apps running inside andibase, so you can build with the same reusable primitives used by the platform. The full list of available components and helpers lives in UI Components.

The embedded runtime also exposes host-action helpers from @andibase/hooks.

  • openDataRecordForm(...) asks the host to open the schema-driven record form drawer.
  • openInlineAgentChat(...) asks the host to open the inline full-screen agent chat drawer.
  • useAndibaseRefreshOnReturn(...) refreshes app state only after the iframe actually returns from blur or hidden state.
import {
  openDataRecordForm,
  openInlineAgentChat,
  useAndibaseRefreshOnReturn,
} from "@andibase/hooks";

openDataRecordForm({
  definitionHandle: "customer",
  defaultValues: { firstName: "Ada" },
});

openDataRecordForm({
  mode: "edit",
  definitionHandle: "customer",
  recordId: "rec_123",
  defaultValues: { firstName: "Ada" },
});

openInlineAgentChat({
  agentHandle: "support-assistant",
});

When an app needs to reload data after a host drawer or chat closes, use useAndibaseRefreshOnReturn(loadData) instead of window.addEventListener("focus", loadData). In iframe apps, the first click often gives the iframe focus, so unconditional focus listeners can make the app appear to reload on the first interaction.

See Embedded Host Actions for the full embedded-runtime API. See Agent Tools for the current runtime tool surface available to agents.


Some things you can do

You do not need to copy the full docs to get started. Your agent can do all of this:

ActionWhat it doesPriority
Start with agent loginGet approved by a human and exchange the device code for a reusable API key.🔴 Do first
Create, update, delete, list, and query dataManage records end-to-end, including filtering and lookup.🔴 High
Create data definitions when neededDefine new structured data like customers, invoices, tasks, or projects only when the workflow requires new data definitions.🟡 Medium
Create and edit appsBuild workspace apps by saving JSX modules and revising the stored code over time.🟠 High
Manage filesStore, organize, and attach files to your workflows.🟠 High
Invite usersBring teammates into the workspace to collaborate.🟡 Medium

Ideas to Try

  • Create a list of potential customers.
  • Track invoices and categorize them, including each file and key extracted data.
  • List todos with priority.

On this page