# REST API

{% hint style="info" %}
The API is available to all users in the **Enterprise** **plan.** If you're interested in testing the API or trialing Enterprise, reach out to our sales team (<sales@arcade.software>).&#x20;
{% endhint %}

The Arcade API is actively being developed and subject to changes. Only a subset of what’s possible in the app is covered by the API. Let us know which features you want to see on the API first!

## Authentication

### How do I authenticate with the API?

First, generate an **API key**:

1. Go to `Settings > Advanced` in your Arcade team dashboard.
2. Generate a new API key.

Then, include the API key in the `authorization` header of all requests:

```
makefileCopyEditauthorization: YOUR_API_KEY
```

All requests are made to `https://api.arcade.software`.

{% @arcade/embed flowId="Qy6aqygmLgMjdyRvDchT" url="<https://app.arcade.software/share/Qy6aqygmLgMjdyRvDchT>" %}

***

## Creating an Arcade from a Video

This API flow lets you programmatically create an Arcade from a video and a list of interaction events.

***

### Step 1: How do I generate an upload URL?

**Method:** `POST`\
**Endpoint:** `/generate-upload-url`\
**URL:** `https://api.arcade.software/generate-upload-url`

#### Headers:

```http
httpCopyEditauthorization: YOUR_API_KEY
content-type: application/json
```

#### Body:

```json
jsonCopyEdit{
  "contentType": "video/webm"
  // or "video/mp4"
  // or "video/quicktime"
}
```

#### Response:

```json
jsonCopyEdit{
  "success": true,
  "uploadUrl": "https://...",
  "uploadId": "my.company-uuid.webm"
}
```

***

### Step 2: How do I upload the video?

**Method:** `PUT`\
**URL:** Use the `uploadUrl` from Step 1

#### Headers:

```http
httpCopyEditcontent-type: video/webm
```

#### Body:

Binary video file (e.g. `.webm`, `.mp4`, or `.mov`)

***

### Step 3: How do I create the Arcade?

**Method:** `POST`\
**URL:** `https://api.arcade.software/arcades`

#### Headers:

```http
httpCopyEditauthorization: YOUR_API_KEY
content-type: application/json
```

#### Body:

```json
jsonCopyEdit{
  "title": "Title of your Arcade",
  "description": "Optional description",
  "uploadId": "your-uploadId from Step 1",
  "events": [
    {
      "type": "click",
      "timestamp": 2.75,
      "target": {
        "x": 400,
        "y": 300
      },
      "label": "Optional hotspot label"
    },
    {
      "type": "scroll",
      "timestamp": 3
    },
    {
      "type": "click",
      "timestamp": 3.5,
      "target": {
        "x": 650,
        "y": 120
      }
    },
    {
      "type": "type",
      "timestamp": 5
    }
  ]
}
```

#### Notes:

* **Click events** create hotspots.
* **Scroll** and **type** events are used to determine if a video step should be created.
* If there’s no scroll or type between clicks, the step will default to an image.

#### Response:

```json
jsonCopyEdit{
  "success": true,
  "arcadeId": "abc123"
}
```

***

## Replacing an Existing Arcade

### Can I update an existing Arcade with a new video and event list?

Yes. Use the same flow as the creation endpoint, but instead of `POST /arcades`, use a different method and endpoint.

**Method:** `PUT`\
**URL:** `https://api.arcade.software/arcades/:id`\
(Replace `:id` with the ID of the Arcade you're updating)

#### Headers:

```http
httpCopyEditauthorization: YOUR_API_KEY
content-type: application/json
```

#### Body:

Same as the **create Arcade** endpoint:

```json
jsonCopyEdit{
  "title": "Updated Arcade Title",
  "description": "Optional new description",
  "uploadId": "your-new-upload-id",
  "events": [ /* same event format */ ]
}
```

This completely replaces the Arcade’s video and interaction steps with the new content.

***

## Arcade User Provisioning API (Public)

This document describes Arcadeʼs user provisioning endpoints for customers\
who want to manage users and teams programmatically.

### Base URL

**Production**

```
https://api.arcade.software
```

### Authentication

All requests must include your **Arcade API key** in the `Authorization` header.

#### Generate an API Key

1. Go to **Settings → Advanced** in your Workspace.
2. Select **New API key**.
3. Enable **User provisioning** in the modal.

> Enabling this grants the API key the required **provisioning scope** for all endpoints below.

#### Example

```bash
curl -sS \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  https://api.arcade.software/users
```

***

### Requirements & Limits

#### Plan Requirement

* Workspace must be on **Growth** or higher.

#### Rate Limiting

* **100 requests per minute per IP**

***

### Error Responses (Common)

All responses are JSON.

#### 401 Unauthorized

```json
{ "error": "Missing authorization header" }
```

```json
{ "error": "Invalid API key" }
```

```json
{ "error": "Workspace is not growth or above" }
```

#### 403 Forbidden

```json
{ "success": false, "error": "This operation requires provisioning scope" }
```

#### 400 Bad Request

```json
{ "success": false, "errors": [...] }
```

#### 5xx Server Errors

```json
{ "success": false, "error": "..." }
```

***

### Users

#### List Users

Returns all **active users** in the workspace.

**Method**

```
GET /users
```

**Auth**

* API key with provisioning scope

**Example**

```bash
curl -sS \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  https://api.arcade.software/users
```

**Response (200)**

```json
{
  "success": true,
  "users": [
    {
      "id": "USER_ID",
      "email": "user@company.com",
      "name": "User Name",
      "role": "Admin"
    }
  ]
}
```

***

#### Create User (Single)

Creates a user **directly** in the workspace (no invite acceptance required).

**Method**

```
POST /users
```

**Roles Allowed**

* Admin
* Editor
* Collaborator
* Viewer
* BillingUser

**Request Body**

```json
{
  "email": "jane.doe@company.com",
  "name": "Jane Doe",
  "role": "Editor"
}
```

**Example**

```bash
curl -sS \
  -X POST \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane.doe@company.com","name":"Jane Doe","role":"Editor"}' \
  https://api.arcade.software/users
```

**Response (201)**

```json
{
  "success": true,
  "user": {
    "id": "USER_ID",
    "email": "jane.doe@company.com",
    "name": "Jane Doe",
    "role": "Editor",
    "status": "Active"
  }
}
```

**Notes**

* If the user already exists, the request fails with **409 Conflict**:

  ```
  User already exists in workspace
  ```

***

#### Create Users (Bulk)

Creates multiple users in a single request. Each user is processed independently.

**Method**

```
POST /users
```

**Request Body**

```json
[
  { "email": "a@company.com", "name": "A", "role": "Admin" },
  { "email": "b@company.com", "name": "B", "role": "Viewer" }
]
```

**Example**

```bash
curl -sS \
  -X POST \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[{"email":"a@company.com","name":"A","role":"Admin"},{"email":"b@company.com","name":"B","role":"Viewer"}]' \
  https://api.arcade.software/users
```

**Response (201)**

```json
{
  "success": true,
  "users": [
    {
      "id": "USER_ID_A",
      "email": "a@company.com",
      "name": "A",
      "role": "Admin",
      "status": "Active"
    },
    {
      "id": "USER_ID_B",
      "email": "b@company.com",
      "name": "B",
      "role": "Viewer",
      "status": "Active"
    }
  ]
}
```

**Notes**

* Duplicate emails **within the same request** return:

  ```json
  { "status": "error", "error": "Duplicate email in request" }
  ```
* Partial failures return `success: false` with per-user errors.

***

#### Delete Users (Bulk)

Deactivates one or more users.

**Method**

```
DELETE /users
```

Users may be identified by **user IDs**, **emails**, or both.

**Delete by User ID**

```bash
curl -sS \
  -X DELETE \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"userIds":["USER_ID_1","USER_ID_2"]}' \
  https://api.arcade.software/users
```

**Delete by Email**

```bash
curl -sS \
  -X DELETE \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"emails":["a@company.com","b@company.com"]}' \
  https://api.arcade.software/users
```

**Response (200)**

```json
{
  "success": true,
  "deleted": 2
}
```

**Notes**

* Deleting the **workspace Owner** is not allowed.
* Partial failures return an `errors` array:

```json
{
  "success": false,
  "deleted": 1,
  "errors": [
    {
      "identifier": "b@company.com",
      "error": "Active user not found"
    }
  ]
}
```

***

### Teams

#### List Teams

Returns all active teams and their active members.

**Method**

```
GET /teams
```

**Example**

```bash
curl -sS \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  https://api.arcade.software/teams
```

**Response (200)**

```json
{
  "success": true,
  "teams": [
    {
      "id": "TEAM_ID",
      "slug": "engineering",
      "name": "Engineering",
      "members": [
        {
          "id": "USER_ID",
          "email": "user@company.com",
          "name": "User Name",
          "type": "Editor"
        }
      ]
    }
  ]
}
```

***

#### Update Team Members (Replace List)

Replaces the team’s entire member list.

> ⚠️ Any existing members **not included** in the new list will be **removed from the team**.

**Method**

```
PATCH /teams/:id/members
```

**Member Types Allowed**

* Admin
* Editor
* Collaborator
* Viewer

**Request Body**

```json
{
  "members": [
    { "userId": "USER_ID_1", "type": "Admin" },
    { "userId": "USER_ID_2", "type": "Viewer" }
  ]
}
```

**Example**

```bash
curl -sS \
  -X PATCH \
  -H "Authorization: YOUR_ARCADE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"members":[{"userId":"USER_ID_1","type":"Admin"},{"userId":"USER_ID_2","type":"Viewer"}]}' \
  https://api.arcade.software/teams/TEAM_ID/members
```

**Response (200)**

```json
{
  "success": true,
  "memberCount": 2
}
```

**Notes**

* Each `userId` must already be an **active workspace member**.
* Errors:
  * `400` – invalid or inactive user
  * `404` – team not found
  * `403` – team belongs to another workspace


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.arcade.software/kb/leverage/advanced-features/rest-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
