Skip to content

API

This section describes the runtime API: routes, request shapes, file handling, trigger webhooks, and error codes.

Base URL: https://app.monkedo.com

Every request requires a valid API key in the Authorization header:

Authorization: Bearer YOUR_API_KEY

A key can only access components you explicitly enabled when configuring the key. Requests for anything else are rejected.

The key's connection is applied automatically. Do not send _connection in inputs. Component schemas returned by the API omit that field.

Every request requires a valid API key in the Authorization header.

A key can only access components you explicitly enabled when configuring the key. Requests for anything else are rejected.

List Available Applications

GET /api/v1/components/apps

List apps this key can use.

Query Parameters

Name

Type

Default

Description

onlyEnabled

Boolean

true

When true, only apps enabled on this key. When false, the full catalog (including built-in Email).

200: OK

[
  {
    "name": "Cubicl",
    "icon": "cubicl.png",
    "key": "cubicl"
  },
  {
    "name": "Email",
    "icon": "trigger/email.png",
    "key": "email"
  }
]

Get Component Definitions

GET /api/v1/components/list

Return definitions (inputs, outputs, descriptions) for all components this key may use.

Query Parameters

Name

Type

Description

appKey

String

Optional. Limit the list to one app (e.g. cubicl, email). Unknown or not-enabled apps return [].

200: OK

[
  {
    "id": "action.cubicl.get-client",
    "name": "Get Client",
    "desc": "Gets client details. [See the docs here](https://docs.cubicl.io/api-integration/clients#get-client-by-id).",
    "appKey": "cubicl",
    "appName": "Cubicl",
    "icon": "cubicl.jpg",
    "isTrigger": false,
    "inputs": {
      "clientId": {
        "title": "clientId",
        "description": "The ID of the client to be retrieved.",
        "type": "string"
      }
    },
    "outputs": {
      "client": {
        "title": "client",
        "type": "object",
        "properties": {}
      }
    },
    "inputsWithQueryableOptions": [],
    "required": ["clientId"]
  }
]

inputs and outputs are JSON Schema. File fields use the shapes described in Files below.

inputsWithQueryableOptions lists input names whose option lists can be loaded through Get Dynamic Input Options. Only present when at least one input supports dynamic options.

Get Component Details

GET /api/v1/components/details/:componentKey

Return the full definition for one component, in the same JSON Schema format as the list endpoint.

Path Parameters

Name

Type

Description

componentKey*

String

Component id — e.g. action.cubicl.get-client

200: OK

// Same object shape as one item from GET /api/v1/components/list.

Get Dynamic Input Options

POST /api/api-keys/input-options

Load the option list for a component input whose choices depend on other inputs (for example, a project list that changes after you pick an account).

Use inputsWithQueryableOptions from the component definition to see which input names support this endpoint.

Body

Name

Type

Description

componentId*

String

Component id — e.g. action.cubicl.get-tasks

inputName*

String

Input whose options you want — e.g. group

inputs

Object

Values of inputs that appear before inputName in the component form

search

String

Optional filter text for searchable option lists

200: OK

[
  { "value": "GROUP_ID_1", "label": "My Project 1", "desc": "GROUP_ID_1" },
  { "value": "GROUP_ID_2", "label": "My Project 2", "desc": "GROUP_ID_2" },
]

The API key's configured connection is used automatically when the component requires authentication.

POST /api/v1/files/upload-link

Reserve a file and get a presigned upload URL. Use this for large files instead of sending base64 in Run Component.

Body

Name

Type

Description

name*

String

File name including extension. Cannot contain /, \, or :.

200: OK

{
  "fileId": "507f1f77bcf86cd799439011",
  "s3Name": "507f1f77bcf86cd799439011-report.pdf",
  "uploadUrl": "https://..."
}
  1. POST this endpoint to get uploadUrl and fileId.

  2. PUT the file bytes to uploadUrl.

  3. Pass { "name": "report.pdf", "fileId": "507f1f77bcf86cd799439011" } as the file input when running a component.

Files uploaded this way are not subject to the 100 MB limit that applies to base64 and URL inputs.

The presigned URL expires after 15 minutes.

Run Component

POST /api/v1/components/:componentId/run

Execute an action.

Path Parameters

Name

Type

Description

componentId*

String

Component id — e.g. action.cubicl.get-client

Body

Name

Type

Description

inputs*

Object

Component inputs. Omit _connection. File inputs use { name, base64 } or { name, url }.

200: OK

{
  "name": "Result name",
  "outputs": {
    "result": "VALUE"
  },
  "componentId": "action.misc.logger",
  "creditsUsed": 1
}

outputs contains raw values, File outputs are { name, size, url }. Paid components may consume credits from your team's balance.

List Registered Triggers

GET /api/v1/components/triggers

200: OK

[
  {
    "_id": "6a295afb530d2213967340c1",
    "componentId": "trigger.cubicl.task-archived",
    "inputs": {
      "group": "GROUP_ID"
    },
    "createdAt": "2026-06-10T12:39:23.183Z",
    "webhookUrl": "https://hooks.example.com/listen"
  }
]

Register Trigger

POST /api/v1/components/triggers

Register a trigger. When it fires, Monkedo POSTs JSON to webhookUrl:

{
  "triggerId": "6a296203f6dd56f7cd1d4313",
  "componentId": "trigger.cubicl.task-created",
  "success": true,
  "outputs": {
    "task": { }
  }
}

File values inside outputs use { name, size, url }, same as run results.

Body

Name

Type

Description

componentKey*

String

Trigger component id — e.g. trigger.cubicl.task-archived or trigger.email

webhookUrl*

String

Absolute public HTTP(S) URL. Localhost and private IPs are rejected.

inputs

Object

Trigger register parameters (varies by component).

200: OK

{
  "triggerId": "6a296203f6dd56f7cd1d4313"
}

webhookUrl must be reachable from the internet. For local development, use a tunnel such as NGROK.

Polling vs webhook triggers

Your webhookUrl is always how you receive events. The difference is how Monkedo learns that something happened in the app:

Webhook triggers

Polling triggers

How Monkedo is notified

The app calls Monkedo as soon as the event happens

Monkedo checks the app on a schedule

When you get the POST

Usually within seconds

After the next poll — there can be a delay

What is reported

The event that just occurred

New items found since the last check (typically only after the trigger was registered)

Unregister Trigger

DELETE /api/v1/components/triggers/:triggerId

Remove a trigger. Returns 404 if the trigger does not belong to this key.

Path Parameters

Name

Type

Description

triggerId*

String

Registered trigger id

200: OK

// Empty

File inputs (including List<File>, such as Send Email attachments):

{
  "name": "note.txt",
  "base64": "SGVsbG8="
}

or a public download URL:

{
  "name": "note.txt",
  "url": "https://example.com/note.txt"
}

or a file reserved through Create File Upload Link:

{
  "name": "note.txt",
  "fileId": "507f1f77bcf86cd799439011"
}

Rules:

  • name is required and must include the extension. It cannot contain /, \, or :.

  • Provide base64, url, or fileId. If both base64 and url are set, base64 is used.

  • Max size is 100 MB for base64 and url inputs. The fileId path has no 100 MB cap.

  • url must be public HTTP(S). Localhost and private IPs are rejected.

File outputs (run results and trigger webhooks):

{
  "name": "report.pdf",
  "size": 2048,
  "url": "https://monkedo.s3.<region>.backblazeb2.com/<object>"
}

Errors are returned as JSON with an HTTP status code:

{
  "statusCode": 403,
  "message": "Invalid API key.",
  "error": "Forbidden"
}

Authentication (403 Forbidden)

Message

Meaning

API key not provided or malformed.

Missing header or incorrect Bearer format

Invalid API key.

Key is wrong, deleted, or regenerated

Authorization (403 Forbidden)

Message

Meaning

the component you are trying to run is not enabled for this api key…

Component not enabled on this key — update the key in the dashboard

API key does not have access to component '…'

Trigger component not enabled on this key

API key does not have access to this component

Dynamic input-options request for a component not enabled on this key

Not found (404)

Message

Meaning

API key not found

Key ID invalid or not in your team

Component '…' not found or not allowed

Unknown component or not enabled on this key

Trigger '…' not found or not owned by this API key

Trigger missing or belongs to another key

Validation (400 Bad Request)

Message

Meaning

Connection not found for app …

Linked account is missing or invalid

App … requires a SMTP/IMAP connection but none was provided.

Multi-auth app (e.g. Email) is missing a required connection

An app has a connection but no components are selected…

Connection set but no components chosen

webhookUrl is required

Trigger register body omitted webhookUrl

webhookUrl must be an absolute HTTP(S) URL

Not a valid http: / https: URI

Localhost and private IP addresses are not supported…

Webhook or file URL is not public

File input must be an object with name and either base64 or url.

File field is not { name, base64 } / { name, url } / { name, fileId }

File name is required.

Missing name

File name cannot include /, , or :.

Invalid file name

File "…" needs base64 contents or a public url.

Neither base64, url, nor fileId was provided

File id "…" is not valid.

fileId is not a valid MongoDB ObjectId

File "…" was not found in this team.

fileId does not exist for this team

File size is too large. Max size is 100 MB.

File exceeds the limit (base64/url path only)

File base64 contents are not valid.

base64 is malformed

File URL is not accessible.

Download from url failed

Input "…" must be an array of files.

A List field was not an array

Invalid component id

Unrecognized component ID

inputName is required.

Dynamic input-options body omitted inputName

Input '…' does not exist on this component.

Unknown input name

Input '…' does not support dynamic options.

Input is not queryable

No connection configured on this API key for app '…'

Auth required but key has no connection for that app

INVALID_NODE_CONNECTION

Linked account expired or revoked at runtime

Runtime failures

Status

Meaning

400

Invalid or incomplete inputs

422

The action ran but failed (e.g. upstream API error)

500

Unexpected server error — contact support if it persists

Replace YOUR_API_KEY with your secret.

# List apps enabled on this key
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://app.monkedo.com/api/v1/components/apps

# List Email components only
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://app.monkedo.com/api/v1/components/list?appKey=email"

# Load dynamic options for an input
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"componentId": "action.cubicl.get-tasks", "inputName": "group", "inputs": {}}' \
  https://app.monkedo.com/api/api-keys/input-options

# Reserve a large file upload
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "large-video.mp4"}' \
  https://app.monkedo.com/api/v1/files/upload-link

# Run an action
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"inputs": {"getOnlyNames": true, "limit": 50, "skip": 0}}' \
  https://app.monkedo.com/api/v1/components/action.cubicl.get-clients/run

# Send email with a file attachment
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "inputs": {
      "to": ["user@example.com"],
      "subject": "File Test",
      "body": "Hello",
      "saveToSent": false,
      "attachments": [{ "name": "note.txt", "base64": "SGVsbG8=" }]
    }
  }' \
  https://app.monkedo.com/api/v1/components/action.email.send-email/run

# Register a trigger (events are POSTed to webhookUrl)
curl -X POST \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "componentKey": "trigger.cubicl.task-created",
    "webhookUrl": "https://hooks.example.com/listen",
    "inputs": { "group": "GROUP_ID" }
  }' \
  https://app.monkedo.com/api/v1/components/triggers