# Agent Auth (/docs/api-reference/agent-auth)

## POST /api/v1/agent/auth/requests

Start agent login

Starts the agent approval flow and returns a short customer code plus a browser verification URL. Agents should send verificationUriComplete to the customer, wait for approval, then poll POST /api/v1/agent/auth/exchange with deviceCode. A successful exchange returns a reusable workspace API key secret in apiKey.key for the HTTP API, not an OAuth token. Effective access is the union of role permissions and explicit permissions. If neither is provided, role defaults to admin.

Tags: Agent Auth

Operation ID: `agentAuth.startAgentLogin`

### Authentication

- `andibaseKey` | type: `apiKey` | in: `header` | name: `x-api-key`

  Authentication is required. Send an API key in x-api-key. The HTTP API also accepts Authorization: Bearer <api-key> and first-party session auth. Agent-login keys are workspace-scoped and reusable until revoked or their configured expiration.

### Request Body

Required: yes

Request Formats

#### Media Type: `application/json`

Schema

schema: `StartAgentLoginInput` | type: `object`

Starts an agent login request and returns a short user code plus a verification URL for the customer. Agents should send verificationUriComplete to the customer, then poll POST /api/v1/agent/auth/exchange with deviceCode until approval or a terminal error. On success, apiKey.key contains a reusable HTTP API key for the approved workspace. Effective access is the union of role permissions and explicit permissions. If neither is provided, role defaults to admin.

Fields

- object | required | schema: `StartAgentLoginInput` | Starts an agent login request and returns a short user code plus a verification URL for the customer. Agents should send verificationUriComplete to the customer, then poll POST /api/v1/agent/auth/exchange with deviceCode until approval or a terminal error. On success, apiKey.key contains a reusable HTTP API key for the approved workspace. Effective access is the union of role permissions and explicit permissions. If neither is provided, role defaults to admin.

  - `agentName` | string | required | schema: `NonEmptyString` | minLength: 1 | a non empty string

  - `agentDescription` | string | optional | schema: `NonEmptyString` | minLength: 1 | a non empty string

  - `workspaceHandle` | string | optional | schema: `NonEmptyString` | minLength: 1 | a non empty string

  - `apiKeyName` | string | optional | schema: `NonEmptyString` | minLength: 1 | a non empty string

  - `role` | string | optional | schema: `AssignableApiKeyRole` | enum: admin, editor, viewer | Hardcoded role available for new workspace API keys

  - `permissions` | object | optional | schema: `WorkspaceApiKeyPermissions` | Explicit permissions attached directly to the API key. Effective access is the union of role permissions and these permissions.

    - `additionalProperties` | array | optional | minItems: 1 | an array of at least 1 item(s)

      - `items` | string | required | schema: `NonEmptyString` | minLength: 1 | a non empty string

  - `apiKeyExpiresInMs` | integer | optional | a positive number

  - `loginExpiresInMs` | integer | optional | a positive number

Examples

#### Example 1

```json
{
  "agentName": "Claude",
  "agentDescription": "Needs read/write access to data and update your workspace data.",
  "workspaceHandle": "acme-growth-team",
  "apiKeyName": "Claude production key",
  "role": "admin",
  "permissions": {
    "apps": [
      "read"
    ]
  },
  "apiKeyExpiresInMs": 2592000000,
  "loginExpiresInMs": 900000
}
```

Examples

#### Example 1

```json
{
  "agentName": "Claude",
  "agentDescription": "Needs read/write access to data and update your workspace data.",
  "workspaceHandle": "acme-growth-team",
  "apiKeyName": "Claude production key",
  "role": "admin",
  "permissions": {
    "apps": [
      "read"
    ]
  },
  "apiKeyExpiresInMs": 2592000000,
  "loginExpiresInMs": 900000
}
```

### Responses

#### 201

Success

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `deviceCode` | string | required

  - `userCode` | string | required

  - `verificationUri` | string | required

  - `verificationUriComplete` | string | required

  - `expiresAt` | string | required

  - `intervalSeconds` | integer | required | a positive number

  - `instructions` | object | required

    - `verificationMessage` | string | required

    - `exchangeMessage` | string | required

    - `apiKeySecretField` | string | required

    - `apiKeySaveHint` | string | required

Examples

#### Example 1

```json
{
  "deviceCode": "0blbPwylJ_5mAZGb29sz8Y-V3CGSHfZ0bj6c5zWd0M8",
  "userCode": "BK7H-3M9Q",
  "verificationUri": "https://andibase.com/agent-login",
  "verificationUriComplete": "https://andibase.com/agent-login?user_code=BK7H-3M9Q",
  "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."
  }
}
```

Examples

#### Example 1

```json
{
  "deviceCode": "0blbPwylJ_5mAZGb29sz8Y-V3CGSHfZ0bj6c5zWd0M8",
  "userCode": "BK7H-3M9Q",
  "verificationUri": "https://andibase.com/agent-login",
  "verificationUriComplete": "https://andibase.com/agent-login?user_code=BK7H-3M9Q",
  "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."
  }
}
```

#### 400

The request did not match the expected schema

Response Formats

#### Media Type: `application/json`

Schema

schema: `HttpApiDecodeError` | type: `object`

The request did not match the expected schema

Fields

- object | required | schema: `HttpApiDecodeError` | The request did not match the expected schema

  - `issues` | array | required

    - `items` | object | required | schema: `Issue` | Represents an error encountered while parsing a value to match the schema

      - `_tag` | string | required | enum: Pointer, Unexpected, Missing, Composite, Refinement, Transformation, Type, Forbidden | The tag identifying the type of parse issue

      - `path` | array | required | The path to the property where the issue occurred

      - `message` | string | required | A descriptive message explaining the issue

  - `message` | string | required

  - `_tag` | string | required | enum: HttpApiDecodeError

#### 500

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: internal_error

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

## GET /api/v1/agent/auth/requests/{userCode}

Get agent login request

Reads the public state of an agent login request by customer-facing code.

Tags: Agent Auth

Operation ID: `agentAuth.getAgentLoginRequest`

### Authentication

- `andibaseKey` | type: `apiKey` | in: `header` | name: `x-api-key`

  Authentication is required. Send an API key in x-api-key. The HTTP API also accepts Authorization: Bearer <api-key> and first-party session auth. Agent-login keys are workspace-scoped and reusable until revoked or their configured expiration.

### Responses

#### 200

Success

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `userCode` | string | required

  - `status` | string | required | schema: `AgentLoginRequestStatus` | enum: pending, approved, denied, issuing, consumed, expired | Device-style agent login request status

  - `agentName` | string | required

  - `agentDescription` | anyOf | required

    - `anyOf[0]` | string | required

    - `anyOf[1]` | null | required

  - `requestedWorkspaceHandle` | anyOf | required

    - `anyOf[0]` | string | required

    - `anyOf[1]` | null | required

  - `role` | string | required | schema: `ApiKeyRole` | enum: admin, editor, viewer, custom | Resolved role for a workspace API key. Legacy keys may appear as custom.

  - `permissions` | anyOf | required

    - `anyOf[0]` | object | required | schema: `WorkspaceApiKeyPermissions` | Explicit permissions attached directly to the API key. Effective access is the union of role permissions and these permissions.

      - `additionalProperties` | array | optional | minItems: 1 | an array of at least 1 item(s)

    - `anyOf[1]` | null | required

  - `apiKeyName` | string | required

  - `expiresAt` | string | required

  - `approvedAt` | anyOf | required

    - `anyOf[0]` | string | required

    - `anyOf[1]` | null | required

  - `deniedAt` | anyOf | required

    - `anyOf[0]` | string | required

    - `anyOf[1]` | null | required

  - `consumedAt` | anyOf | required

    - `anyOf[0]` | string | required

    - `anyOf[1]` | null | required

  - `approvedWorkspace` | anyOf | required

    - `anyOf[0]` | object | required | schema: `Workspace` | Workspace representation visible to members

      - `handle` | string | required

      - `name` | string | required

      - `createdAt` | string | required

      - `updatedAt` | string | required

      - `deletedAt` | anyOf | required

    - `anyOf[1]` | null | required

Examples

#### Example 1

```json
{
  "userCode": "BK7H-3M9Q",
  "status": "pending",
  "agentName": "Claude",
  "agentDescription": "Needs read/write access to data and update your workspace data.",
  "requestedWorkspaceHandle": "acme-growth-team",
  "role": "admin",
  "permissions": {
    "apps": [
      "read"
    ]
  },
  "apiKeyName": "Claude production key",
  "expiresAt": "2026-03-07T18:15:00.000Z",
  "approvedAt": null,
  "deniedAt": null,
  "consumedAt": null,
  "approvedWorkspace": null
}
```

Examples

#### Example 1

```json
{
  "userCode": "BK7H-3M9Q",
  "status": "pending",
  "agentName": "Claude",
  "agentDescription": "Needs read/write access to data and update your workspace data.",
  "requestedWorkspaceHandle": "acme-growth-team",
  "role": "admin",
  "permissions": {
    "apps": [
      "read"
    ]
  },
  "apiKeyName": "Claude production key",
  "expiresAt": "2026-03-07T18:15:00.000Z",
  "approvedAt": null,
  "deniedAt": null,
  "consumedAt": null,
  "approvedWorkspace": null
}
```

#### 400

The request did not match the expected schema

Response Formats

#### Media Type: `application/json`

Schema

schema: `HttpApiDecodeError` | type: `object`

The request did not match the expected schema

Fields

- object | required | schema: `HttpApiDecodeError` | The request did not match the expected schema

  - `issues` | array | required

    - `items` | object | required | schema: `Issue` | Represents an error encountered while parsing a value to match the schema

      - `_tag` | string | required | enum: Pointer, Unexpected, Missing, Composite, Refinement, Transformation, Type, Forbidden | The tag identifying the type of parse issue

      - `path` | array | required | The path to the property where the issue occurred

      - `message` | string | required | A descriptive message explaining the issue

  - `message` | string | required

  - `_tag` | string | required | enum: HttpApiDecodeError

#### 404

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: not_found

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "not_found",
  "message": "The requested resource was not found."
}
```

Examples

#### Example 1

```json
{
  "code": "not_found",
  "message": "The requested resource was not found."
}
```

#### 500

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: internal_error

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

## POST /api/v1/agent/auth/requests/{userCode}/approve

Approve agent login

Approves a pending agent login request for the signed-in customer and selected workspace.

Tags: Agent Auth

Operation ID: `agentAuth.approveAgentLogin`

### Authentication

- `andibaseKey` | type: `apiKey` | in: `header` | name: `x-api-key`

  Authentication is required. Send an API key in x-api-key. The HTTP API also accepts Authorization: Bearer <api-key> and first-party session auth. Agent-login keys are workspace-scoped and reusable until revoked or their configured expiration.

### Request Body

Required: yes

Request Formats

#### Media Type: `application/json`

Schema

schema: `ApproveAgentLoginInput` | type: `object`

Approves an agent login request for one workspace. When the request already targets a workspace, this field can be omitted.

Fields

- object | required | schema: `ApproveAgentLoginInput` | Approves an agent login request for one workspace. When the request already targets a workspace, this field can be omitted.

  - `workspaceHandle` | string | optional | schema: `NonEmptyString` | minLength: 1 | a non empty string

Examples

#### Example 1

```json
{
  "workspaceHandle": "acme-growth-team"
}
```

Examples

#### Example 1

```json
{
  "workspaceHandle": "acme-growth-team"
}
```

### Responses

#### 200

Success

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `status` | string | required | enum: approved

  - `workspace` | object | required | schema: `Workspace` | Workspace representation visible to members

    - `handle` | string | required

    - `name` | string | required

    - `createdAt` | string | required

    - `updatedAt` | string | required

    - `deletedAt` | anyOf | required

      - `anyOf[0]` | string | required

      - `anyOf[1]` | null | required

  - `approvedAt` | string | required

Examples

#### Example 1

```json
{
  "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
  },
  "approvedAt": "2026-03-07T18:05:00.000Z"
}
```

Examples

#### Example 1

```json
{
  "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
  },
  "approvedAt": "2026-03-07T18:05:00.000Z"
}
```

#### 400

The request did not match the expected schema

Response Formats

#### Media Type: `application/json`

Schema

type: `anyOf`

Fields

- anyOf | required

  - `anyOf[0]` | object | required | schema: `HttpApiDecodeError` | The request did not match the expected schema

    - `issues` | array | required

      - `items` | object | required | schema: `Issue` | Represents an error encountered while parsing a value to match the schema

    - `message` | string | required

    - `_tag` | string | required | enum: HttpApiDecodeError

  - `anyOf[1]` | object | required

    - `code` | string | required | schema: `AgentAuthErrorCode` | enum: authorization_pending, access_denied, expired_token, invalid_grant, slow_down, workspace_required | Machine-readable agent login error code

    - `message` | string | required

#### 401

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: authentication_required, invalid_api_key, session_required

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "authentication_required",
  "message": "Authentication required. Send Authorization: Bearer <api-key>, x-api-key, or a signed-in session."
}
```

#### Example 2

```json
{
  "code": "invalid_api_key",
  "message": "The provided API key is invalid, expired, revoked, or malformed."
}
```

Examples

#### Example 1

```json
{
  "code": "authentication_required",
  "message": "Authentication required. Send Authorization: Bearer <api-key>, x-api-key, or a signed-in session."
}
```

#### Example 2

```json
{
  "code": "invalid_api_key",
  "message": "The provided API key is invalid, expired, revoked, or malformed."
}
```

#### 500

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: internal_error

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

## POST /api/v1/agent/auth/requests/{userCode}/deny

Deny agent login

Denies a pending agent login request so the agent stops polling and the device code cannot be exchanged.

Tags: Agent Auth

Operation ID: `agentAuth.denyAgentLogin`

### Authentication

- `andibaseKey` | type: `apiKey` | in: `header` | name: `x-api-key`

  Authentication is required. Send an API key in x-api-key. The HTTP API also accepts Authorization: Bearer <api-key> and first-party session auth. Agent-login keys are workspace-scoped and reusable until revoked or their configured expiration.

### Responses

#### 200

Success

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `status` | string | required | enum: denied

  - `deniedAt` | string | required

Examples

#### Example 1

```json
{
  "status": "denied",
  "deniedAt": "2026-03-07T18:04:00.000Z"
}
```

Examples

#### Example 1

```json
{
  "status": "denied",
  "deniedAt": "2026-03-07T18:04:00.000Z"
}
```

#### 400

The request did not match the expected schema

Response Formats

#### Media Type: `application/json`

Schema

type: `anyOf`

Fields

- anyOf | required

  - `anyOf[0]` | object | required | schema: `HttpApiDecodeError` | The request did not match the expected schema

    - `issues` | array | required

      - `items` | object | required | schema: `Issue` | Represents an error encountered while parsing a value to match the schema

    - `message` | string | required

    - `_tag` | string | required | enum: HttpApiDecodeError

  - `anyOf[1]` | object | required

    - `code` | string | required | schema: `AgentAuthErrorCode` | enum: authorization_pending, access_denied, expired_token, invalid_grant, slow_down, workspace_required | Machine-readable agent login error code

    - `message` | string | required

#### 401

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: authentication_required, invalid_api_key, session_required

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "authentication_required",
  "message": "Authentication required. Send Authorization: Bearer <api-key>, x-api-key, or a signed-in session."
}
```

#### Example 2

```json
{
  "code": "invalid_api_key",
  "message": "The provided API key is invalid, expired, revoked, or malformed."
}
```

Examples

#### Example 1

```json
{
  "code": "authentication_required",
  "message": "Authentication required. Send Authorization: Bearer <api-key>, x-api-key, or a signed-in session."
}
```

#### Example 2

```json
{
  "code": "invalid_api_key",
  "message": "The provided API key is invalid, expired, revoked, or malformed."
}
```

#### 500

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: internal_error

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

## POST /api/v1/agent/auth/exchange

Exchange agent login

Polls the agent login request using deviceCode and, once approved, issues a reusable workspace-scoped API key. The secret is returned once at apiKey.key, should be saved immediately, and should be reused for future HTTP API calls instead of re-running login.

Tags: Agent Auth

Operation ID: `agentAuth.exchangeAgentLogin`

### Authentication

- `andibaseKey` | type: `apiKey` | in: `header` | name: `x-api-key`

  Authentication is required. Send an API key in x-api-key. The HTTP API also accepts Authorization: Bearer <api-key> and first-party session auth. Agent-login keys are workspace-scoped and reusable until revoked or their configured expiration.

### Request Body

Required: yes

Request Formats

#### Media Type: `application/json`

Schema

schema: `ExchangeAgentLoginInput` | type: `object`

Poll this endpoint with deviceCode until approval or a terminal error. On success it returns a reusable workspace-scoped HTTP API key at apiKey.key. This is not an OAuth token. Persist the secret immediately because it is returned once.

Fields

- object | required | schema: `ExchangeAgentLoginInput` | Poll this endpoint with deviceCode until approval or a terminal error. On success it returns a reusable workspace-scoped HTTP API key at apiKey.key. This is not an OAuth token. Persist the secret immediately because it is returned once.

  - `deviceCode` | string | required | schema: `NonEmptyString` | minLength: 1 | a non empty string

Examples

#### Example 1

```json
{
  "deviceCode": "0blbPwylJ_5mAZGb29sz8Y-V3CGSHfZ0bj6c5zWd0M8"
}
```

Examples

#### Example 1

```json
{
  "deviceCode": "0blbPwylJ_5mAZGb29sz8Y-V3CGSHfZ0bj6c5zWd0M8"
}
```

### Responses

#### 200

Success

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `status` | string | required | enum: approved

  - `workspace` | object | required | schema: `Workspace` | Workspace representation visible to members

    - `handle` | string | required

    - `name` | string | required

    - `createdAt` | string | required

    - `updatedAt` | string | required

    - `deletedAt` | anyOf | required

      - `anyOf[0]` | string | required

      - `anyOf[1]` | null | required

  - `apiKey` | object | required

    - `key` | string | required

    - `apiKey` | object | required | schema: `WorkspaceApiKey` | Workspace-scoped API key metadata

      - `id` | string | required

      - `name` | anyOf | required

      - `start` | anyOf | required

      - `prefix` | anyOf | required

      - `enabled` | boolean | required

      - `role` | string | required | schema: `ApiKeyRole` | enum: admin, editor, viewer, custom | Resolved role for a workspace API key. Legacy keys may appear as custom.

      - `permissions` | anyOf | required

      - `createdAt` | string | required

      - `updatedAt` | string | required

      - `expiresAt` | anyOf | required

      - `lastRequest` | anyOf | required

  - `usage` | object | required

    - `saveHint` | string | required

    - `recommendedEnvVar` | string | required

    - `authorizationHeader` | string | required

    - `secretField` | string | required

    - `lifecycle` | string | required

Examples

#### Example 1

```json
{
  "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_3x7X7uPKnd2m4WQNkfC2fZb3TW4nYJd1",
    "apiKey": {
      "id": "key_6ZW0qF8cXTWETrdFM3A7yv",
      "name": "Claude production key",
      "start": "andi_l",
      "prefix": "andi_",
      "enabled": true,
      "role": "admin",
      "permissions": {
        "apps": [
          "read"
        ]
      },
      "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."
  }
}
```

Examples

#### Example 1

```json
{
  "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_3x7X7uPKnd2m4WQNkfC2fZb3TW4nYJd1",
    "apiKey": {
      "id": "key_6ZW0qF8cXTWETrdFM3A7yv",
      "name": "Claude production key",
      "start": "andi_l",
      "prefix": "andi_",
      "enabled": true,
      "role": "admin",
      "permissions": {
        "apps": [
          "read"
        ]
      },
      "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."
  }
}
```

#### 400

The request did not match the expected schema

Response Formats

#### Media Type: `application/json`

Schema

type: `anyOf`

Fields

- anyOf | required

  - `anyOf[0]` | object | required | schema: `HttpApiDecodeError` | The request did not match the expected schema

    - `issues` | array | required

      - `items` | object | required | schema: `Issue` | Represents an error encountered while parsing a value to match the schema

    - `message` | string | required

    - `_tag` | string | required | enum: HttpApiDecodeError

  - `anyOf[1]` | object | required

    - `code` | string | required | schema: `AgentAuthErrorCode` | enum: authorization_pending, access_denied, expired_token, invalid_grant, slow_down, workspace_required | Machine-readable agent login error code

    - `message` | string | required

#### 500

Error

Response Formats

#### Media Type: `application/json`

Schema

type: `object`

Fields

- object | required

  - `code` | string | required | enum: internal_error

  - `message` | string | required

  - `details` | object | optional | schema: `ApiErrorDetails` | Optional machine-readable error details

    - `additionalProperties` | string | optional

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

Examples

#### Example 1

```json
{
  "code": "internal_error",
  "message": "An unexpected server error occurred."
}
```

## Documentation Navigation
Use these paths to traverse the relevant docs and generated API reference files for the app.
- Agent Auth [current] -> `/docs/api-reference/agent-auth`
- andibase Overview -> `/docs` (source: `content/docs/index.mdx`)
- Get started (for AI Agents) -> `/docs/agent-get-started` (source: `content/docs/agent-get-started.mdx`)
- Agent Tools -> `/docs/agent-tools` (source: `content/docs/agent-tools.mdx`)
- Agents -> `/docs/agents` (source: `content/docs/agents.mdx`)
- Get agent login request -> `/docs/api-reference/agent-auth/get-api-v1-agent-auth-requests-usercode`
- Exchange agent login -> `/docs/api-reference/agent-auth/post-api-v1-agent-auth-exchange`
- Start agent login -> `/docs/api-reference/agent-auth/post-api-v1-agent-auth-requests`
- Approve agent login -> `/docs/api-reference/agent-auth/post-api-v1-agent-auth-requests-usercode-approve`
- Deny agent login -> `/docs/api-reference/agent-auth/post-api-v1-agent-auth-requests-usercode-deny`
- Agents -> `/docs/api-reference/agents`
- Delete workspace agent -> `/docs/api-reference/agents/delete-api-v1-agents-id`
- List workspace agents -> `/docs/api-reference/agents/get-api-v1-agents`
- Get workspace agent -> `/docs/api-reference/agents/get-api-v1-agents-id`
- List agent chats -> `/docs/api-reference/agents/get-api-v1-agents-id-chats`
- Get agent chat -> `/docs/api-reference/agents/get-api-v1-agents-id-chats-chatid`
- Update workspace agent -> `/docs/api-reference/agents/patch-api-v1-agents-id`
- Create workspace agent -> `/docs/api-reference/agents/post-api-v1-agents`
- Send agent message -> `/docs/api-reference/agents/post-api-v1-agents-id-chats-chatid-messages`
- Apps -> `/docs/api-reference/apps`
- Delete app -> `/docs/api-reference/apps/delete-api-v1-apps-id`
- List workspace apps -> `/docs/api-reference/apps/get-api-v1-apps`
- Get app by id -> `/docs/api-reference/apps/get-api-v1-apps-id`
- Update app -> `/docs/api-reference/apps/patch-api-v1-apps-id`
- Create app -> `/docs/api-reference/apps/post-api-v1-apps`
- Automations -> `/docs/api-reference/automations`
- Delete workspace automation -> `/docs/api-reference/automations/delete-api-v1-automations-id`
- List workspace automations -> `/docs/api-reference/automations/get-api-v1-automations`
- Get workspace automation -> `/docs/api-reference/automations/get-api-v1-automations-id`
- List automation runs -> `/docs/api-reference/automations/get-api-v1-automations-id-runs`
- Get automation run -> `/docs/api-reference/automations/get-api-v1-automations-id-runs-runid`
- Update workspace automation -> `/docs/api-reference/automations/patch-api-v1-automations-id`
- Create workspace automation -> `/docs/api-reference/automations/post-api-v1-automations`
- Run automation -> `/docs/api-reference/automations/post-api-v1-automations-id-run`
- Trigger automation webhook -> `/docs/api-reference/automations/post-api-v1-automations-webhooks-publicid-secret`
- Channels -> `/docs/api-reference/channels`
- Delete channel -> `/docs/api-reference/channels/delete-api-v1-channels-channelid`
- List channels -> `/docs/api-reference/channels/get-api-v1-channels`
- Get channel -> `/docs/api-reference/channels/get-api-v1-channels-channelid`
- Update channel -> `/docs/api-reference/channels/patch-api-v1-channels-channelid`
- Create channel -> `/docs/api-reference/channels/post-api-v1-channels`
- Data -> `/docs/api-reference/data`
- Data Definitions -> `/docs/api-reference/data-definitions`
- Delete data definition -> `/docs/api-reference/data-definitions/delete-api-v1-data-definitions-id`
- List data definitions -> `/docs/api-reference/data-definitions/get-api-v1-data-definitions`
- Get data definition -> `/docs/api-reference/data-definitions/get-api-v1-data-definitions-id`
- Update data definition -> `/docs/api-reference/data-definitions/patch-api-v1-data-definitions-id`
- Create data definition -> `/docs/api-reference/data-definitions/post-api-v1-data-definitions`
- Data SQL Query -> `/docs/api-reference/data-sql-query`
- Run SQL query against workspace data -> `/docs/api-reference/data-sql-query/post-api-v1-data-sql-query`
- Get data by id -> `/docs/api-reference/data/get-api-v1-data-definitions-definitionid-data-id`
- Select all data row ids -> `/docs/api-reference/data/get-api-v1-data-definitions-definitionid-data-select-all`
- List data -> `/docs/api-reference/data/get-api-v1-data-definitions-definitionid-query`
- Patch many data rows -> `/docs/api-reference/data/patch-api-v1-data-definitions-definitionid-data-patch-many`
- Delete many data rows -> `/docs/api-reference/data/post-api-v1-data-definitions-definitionid-data-delete-many`
- Upsert many data rows -> `/docs/api-reference/data/post-api-v1-data-definitions-definitionid-data-upsert-many`
- DuckDB Query -> `/docs/api-reference/duckdb-query`
- Run a DuckDB query against registered sources -> `/docs/api-reference/duckdb-query/post-api-v1-duckdb-query`
- Explorer -> `/docs/api-reference/explorer`
- Delete explorer folder -> `/docs/api-reference/explorer/delete-api-v1-workspace-nodes-nodeid`
- List explorer nodes -> `/docs/api-reference/explorer/get-api-v1-workspace-nodes`
- List explorer folders -> `/docs/api-reference/explorer/get-api-v1-workspace-nodes-folders`
- Rename explorer folder -> `/docs/api-reference/explorer/patch-api-v1-workspace-nodes-nodeid-rename`
- Create folder -> `/docs/api-reference/explorer/post-api-v1-workspace-nodes-folders`
- Move explorer node -> `/docs/api-reference/explorer/post-api-v1-workspace-nodes-nodeid-move`
- Files -> `/docs/api-reference/files`
- List workspace files -> `/docs/api-reference/files/get-api-v1-files`
- Read file content -> `/docs/api-reference/files/get-api-v1-files-fileid-content`
- Create file -> `/docs/api-reference/files/post-api-v1-files`
- Complete file upload -> `/docs/api-reference/files/post-api-v1-files-fileid-complete`
- Presign multipart parts -> `/docs/api-reference/files/post-api-v1-files-fileid-parts`
- Update file content -> `/docs/api-reference/files/put-api-v1-files-fileid-content`
- Messages -> `/docs/api-reference/messages`
- List channel messages -> `/docs/api-reference/messages/get-api-v1-channels-channelid-messages`
- List thread messages -> `/docs/api-reference/messages/get-api-v1-channels-channelid-threads-threadid-messages`
- Create channel message -> `/docs/api-reference/messages/post-api-v1-channels-channelid-messages`
- Create thread message -> `/docs/api-reference/messages/post-api-v1-channels-channelid-threads-threadid-messages`
- Notifications -> `/docs/api-reference/notifications`
- List notification devices -> `/docs/api-reference/notifications/get-api-v1-notifications-devices`
- Check Expo notification receipts -> `/docs/api-reference/notifications/post-api-v1-notifications-receipts`
- Send workspace notifications -> `/docs/api-reference/notifications/post-api-v1-notifications-send`
- Runs -> `/docs/api-reference/runs`
- List workspace runs -> `/docs/api-reference/runs/get-api-v1-runs`
- Get workspace run -> `/docs/api-reference/runs/get-api-v1-runs-runid`
- Threads -> `/docs/api-reference/threads`
- List channel threads -> `/docs/api-reference/threads/get-api-v1-channels-channelid-threads`
- Get thread -> `/docs/api-reference/threads/get-api-v1-channels-channelid-threads-threadid`
- Create thread -> `/docs/api-reference/threads/post-api-v1-channels-channelid-threads`
- Workflows -> `/docs/api-reference/workflows`
- Delete workflow definition -> `/docs/api-reference/workflows/delete-api-v1-workflows-id`
- List workflow definitions -> `/docs/api-reference/workflows/get-api-v1-workflows`
- Get workflow definition -> `/docs/api-reference/workflows/get-api-v1-workflows-id`
- Update workflow definition -> `/docs/api-reference/workflows/patch-api-v1-workflows-id`
- Create workflow definition -> `/docs/api-reference/workflows/post-api-v1-workflows`
- Workspaces -> `/docs/api-reference/workspaces`
- Delete workspace API key -> `/docs/api-reference/workspaces/delete-api-v1-workspaces-workspacehandle-api-keys-keyid`
- Delete workspace credential -> `/docs/api-reference/workspaces/delete-api-v1-workspaces-workspacehandle-credentials-credentialid`
- Delete workspace invitation -> `/docs/api-reference/workspaces/delete-api-v1-workspaces-workspacehandle-invitations-invitationid`
- Delete workspace user -> `/docs/api-reference/workspaces/delete-api-v1-workspaces-workspacehandle-users-userid`
- List my workspaces -> `/docs/api-reference/workspaces/get-api-v1-workspaces`
- List workspace API keys -> `/docs/api-reference/workspaces/get-api-v1-workspaces-workspacehandle-api-keys`
- List workspace credentials -> `/docs/api-reference/workspaces/get-api-v1-workspaces-workspacehandle-credentials`
- List workspace credential tools -> `/docs/api-reference/workspaces/get-api-v1-workspaces-workspacehandle-credentials-credentialid-tools`
- List workspace invitations -> `/docs/api-reference/workspaces/get-api-v1-workspaces-workspacehandle-invitations`
- List workspace users -> `/docs/api-reference/workspaces/get-api-v1-workspaces-workspacehandle-users`
- Create workspace -> `/docs/api-reference/workspaces/post-api-v1-workspaces`
- Create workspace API key -> `/docs/api-reference/workspaces/post-api-v1-workspaces-workspacehandle-api-keys`
- Create workspace credential -> `/docs/api-reference/workspaces/post-api-v1-workspaces-workspacehandle-credentials`
- Invite user to workspace -> `/docs/api-reference/workspaces/post-api-v1-workspaces-workspacehandle-invitations`
- Create workspace user -> `/docs/api-reference/workspaces/post-api-v1-workspaces-workspacehandle-users`
- Apps -> `/docs/apps` (source: `content/docs/apps.mdx`)
- Authentication -> `/docs/authentication` (source: `content/docs/authentication.mdx`)
- Building Blocks -> `/docs/building-blocks` (source: `content/docs/building-blocks.mdx`)
- Data Model -> `/docs/data-model` (source: `content/docs/data-model.mdx`)
- Embedded Host Actions -> `/docs/embedded-host-actions` (source: `content/docs/embedded-host-actions.mdx`)
- Introduction -> `/docs/introduction` (source: `content/docs/introduction.mdx`)
- Recipes -> `/docs/receipes` (source: `content/docs/receipes/index.mdx`)
- Construction Site Visit Agent -> `/docs/receipes/construction-site-visit-agent` (source: `content/docs/receipes/construction-site-visit-agent.mdx`)
- Daily Lead Qualification Agent -> `/docs/receipes/daily-lead-qualification-agent` (source: `content/docs/receipes/daily-lead-qualification-agent.mdx`)
- Day Planner Agent -> `/docs/receipes/day-planner-agent` (source: `content/docs/receipes/day-planner-agent.mdx`)
- Expense Tracker -> `/docs/receipes/expense-tracker` (source: `content/docs/receipes/expense-tracker.mdx`)
- Legal Case Tracker -> `/docs/receipes/legal-case-tracker` (source: `content/docs/receipes/legal-case-tracker.mdx`)
- Spare Parts Request Agent -> `/docs/receipes/spare-parts-request-agent` (source: `content/docs/receipes/spare-parts-request-agent.mdx`)
- Weekly Report Email Agent -> `/docs/receipes/weekly-report-email-agent` (source: `content/docs/receipes/weekly-report-email-agent.mdx`)
- UI Components -> `/docs/ui-components` (source: `content/docs/ui-components.mdx`)