Get started (for AI Agents)
andibase
Build and operate AI-native workflows with one shared system for AI agents & humans.
Skill Files
| File | URL |
|---|---|
| SKILL.md (this file) | https://andibase.com/skill.md |
| Docs.md | https://andibase.com/docs.md |
| Recipes | https://andibase.com/docs/receipes |
Install locally:
mkdir -p ~/.agents/skills/andibase
curl -s https://andibase.com/skill.md > ~/.agents/skills/andibase/SKILL.mdOr 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 humandeviceCode: use this for polling and exchange
Agent flow in 4 steps
- Call
POST /api/v1/agent/auth/requests. - Show the human
verificationUriComplete. - Poll
POST /api/v1/agent/auth/exchangewithdeviceCode. - Save
apiKey.keyand 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, orinvalid_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.keyexactly 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
| Response | Meaning | Agent action |
|---|---|---|
authorization_pending | The human has not approved yet | Sleep and poll again |
slow_down | You are polling too quickly | Wait longer, then retry |
access_denied | The human rejected the request | Stop and ask for a new login |
expired_token | The login request expired | Start a new login |
invalid_grant | The deviceCode is invalid, already consumed, or no longer usable | Start a new login |
| success | The request was approved and the key was issued | Save 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/appscreates a new app.PATCH /api/v1/apps/:handleupdates an existing app.GET /api/v1/apps/:idreturns the full saved app, includingcode.
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
codeas 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/uiand 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/uiprimitives as much as possible before reaching for custom CSS or Tailwind. - Keep the default
shadcn/uistyling 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:
| Action | What it does | Priority |
|---|---|---|
| Start with agent login | Get approved by a human and exchange the device code for a reusable API key. | 🔴 Do first |
| Create, update, delete, list, and query data | Manage records end-to-end, including filtering and lookup. | 🔴 High |
| Create data definitions when needed | Define new structured data like customers, invoices, tasks, or projects only when the workflow requires new data definitions. | 🟡 Medium |
| Create and edit apps | Build workspace apps by saving JSX modules and revising the stored code over time. | 🟠 High |
| Manage files | Store, organize, and attach files to your workflows. | 🟠 High |
| Invite users | Bring 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.