Automation.
Hot folders and sync jobs are administrator calls and need the automation feature once you pass the free allowance. Event rules are for the rule's owner, and an administrator sees every rule. In Free mode one automation job runs.
See the API reference for the key and for errors. The guide to what a rule can do is Event rules.
Hot folders
GET /api/v1/hot-folders
Watched folders.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Success. 200.
The body is an array.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
rootId | string | required | The id. |
rootName | string | required | The storage location's name. |
path | string | required | A path relative to the space or the storage location, with / between folders and no leading slash. |
settleSecs | integer | required | |
destination | string | required | |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
afterSend | string | required | What happens to the original once it has gone: leave, move or delete. |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | When the runner last looked at this folder. Absent until it has. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. This is what turns "nothing is happening" into something an administrator can fix. |
createdAt | string | required | A time, as RFC 3339. |
[
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"rootId": "k7Qm2sLp9vX4aB1c",
"rootName": "example",
"path": "projects/rush",
"settleSecs": 1,
"destination": "example",
"destKind": "example",
"afterSend": "example",
"enabled": true,
"createdAt": "2026-10-05T18:00:00Z"
}
]
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}
POST /api/v1/hot-folders
Watch a folder.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Request body. JSON.
A field the server does not know is refused with 400.
| Field | Type | Meaning | |
|---|---|---|---|
name | string | required | The name. |
rootId | string | optional | The location, for a caller that still names storage directly. |
spaceId | string | optional | The space, when the folder was chosen from Home. |
path | string | optional | A path relative to the space or the storage location, with / between folders and no leading slash. |
settleSecs | integer | optional | |
destination | string | required | |
destKind | string | required | What the destination means. Required on a new folder: there is no sensible default, and guessing is the thing this field exists to stop. |
afterSend | string | optional |
{
"name": "Rush delivery",
"rootId": "k7Qm2sLp9vX4aB1c",
"spaceId": "k7Qm2sLp9vX4aB1c",
"path": "projects/rush",
"settleSecs": 1,
"destination": "example",
"destKind": "example",
"afterSend": "example"
}
Success. 200.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
rootId | string | required | The id. |
rootName | string | required | The storage location's name. |
path | string | required | A path relative to the space or the storage location, with / between folders and no leading slash. |
settleSecs | integer | required | |
destination | string | required | |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
afterSend | string | required | What happens to the original once it has gone: leave, move or delete. |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | When the runner last looked at this folder. Absent until it has. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. This is what turns "nothing is happening" into something an administrator can fix. |
createdAt | string | required | A time, as RFC 3339. |
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"rootId": "k7Qm2sLp9vX4aB1c",
"rootName": "example",
"path": "projects/rush",
"settleSecs": 1,
"destination": "example",
"destKind": "example",
"afterSend": "example",
"enabled": true,
"createdAt": "2026-10-05T18:00:00Z"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}
PATCH /api/v1/hot-folders/{id}
Change one.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. JSON.
A field the server does not know is refused with 400.
| Field | Type | Meaning | |
|---|---|---|---|
name | string | optional | The name. |
path | string | optional | A path relative to the space or the storage location, with / between folders and no leading slash. |
settleSecs | integer | optional | |
destination | string | optional | |
destKind | string | optional | |
afterSend | string | optional | |
enabled | boolean | optional |
{
"name": "Rush delivery",
"path": "projects/rush",
"settleSecs": 1,
"destination": "example",
"destKind": "example",
"afterSend": "example",
"enabled": true
}
Success. 200.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
rootId | string | required | The id. |
rootName | string | required | The storage location's name. |
path | string | required | A path relative to the space or the storage location, with / between folders and no leading slash. |
settleSecs | integer | required | |
destination | string | required | |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
afterSend | string | required | What happens to the original once it has gone: leave, move or delete. |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | When the runner last looked at this folder. Absent until it has. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. This is what turns "nothing is happening" into something an administrator can fix. |
createdAt | string | required | A time, as RFC 3339. |
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"rootId": "k7Qm2sLp9vX4aB1c",
"rootName": "example",
"path": "projects/rush",
"settleSecs": 1,
"destination": "example",
"destKind": "example",
"afterSend": "example",
"enabled": true,
"createdAt": "2026-10-05T18:00:00Z"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
DELETE /api/v1/hot-folders/{id}
Stop watching.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Success. 200.
The reply has no body.
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
Sync jobs
GET /api/v1/sync-jobs
One-way sync jobs.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Success. 200.
The body is an array.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
sourceRoot | string | required | |
sourceRootName | string | required | |
sourcePath | string | required | |
destination | string | required | |
schedule | string | required | |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | A time, as RFC 3339. |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
nextRunAt | string | optional, left out when empty | When the schedule says it should next go. Absent for a job that is not on a timer. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. |
createdAt | string | required | A time, as RFC 3339. |
[
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"sourceRoot": "example",
"sourceRootName": "example",
"sourcePath": "projects/rush",
"destination": "example",
"schedule": "example",
"enabled": true,
"destKind": "example",
"createdAt": "2026-10-05T18:00:00Z"
}
]
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}
POST /api/v1/sync-jobs
Add one.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Request body. JSON.
A field the server does not know is refused with 400.
| Field | Type | Meaning | |
|---|---|---|---|
name | string | required | The name. |
sourceRoot | string | optional | The location, for a caller that still names storage directly. |
spaceId | string | optional | The space, when the folder was chosen from Home. |
sourcePath | string | optional | |
destination | string | required | |
schedule | string | optional | |
destKind | string | required | What the destination means. Required: there is no sensible default, and guessing is what this field exists to stop. |
{
"name": "Rush delivery",
"sourceRoot": "example",
"spaceId": "k7Qm2sLp9vX4aB1c",
"sourcePath": "projects/rush",
"destination": "example",
"schedule": "example",
"destKind": "example"
}
Success. 200.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
sourceRoot | string | required | |
sourceRootName | string | required | |
sourcePath | string | required | |
destination | string | required | |
schedule | string | required | |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | A time, as RFC 3339. |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
nextRunAt | string | optional, left out when empty | When the schedule says it should next go. Absent for a job that is not on a timer. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. |
createdAt | string | required | A time, as RFC 3339. |
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"sourceRoot": "example",
"sourceRootName": "example",
"sourcePath": "projects/rush",
"destination": "example",
"schedule": "example",
"enabled": true,
"destKind": "example",
"createdAt": "2026-10-05T18:00:00Z"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}
PATCH /api/v1/sync-jobs/{id}
Change one.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. JSON.
A field the server does not know is refused with 400.
| Field | Type | Meaning | |
|---|---|---|---|
name | string | optional | The name. |
sourcePath | string | optional | |
destination | string | optional | |
schedule | string | optional | |
destKind | string | optional | |
enabled | boolean | optional |
{
"name": "Rush delivery",
"sourcePath": "projects/rush",
"destination": "example",
"schedule": "example",
"destKind": "example",
"enabled": true
}
Success. 200.
| Field | Type | Meaning | |
|---|---|---|---|
id | string | required | The id. |
name | string | required | The name. |
sourceRoot | string | required | |
sourceRootName | string | required | |
sourcePath | string | required | |
destination | string | required | |
schedule | string | required | |
enabled | boolean | required | |
pausedReason | string | optional, left out when empty | |
lastRunAt | string | optional, left out when empty | A time, as RFC 3339. |
destKind | string | required | What the destination means. unset is a row from before kinds existed; the runner refuses those rather than guessing. |
nextRunAt | string | optional, left out when empty | When the schedule says it should next go. Absent for a job that is not on a timer. |
lastError | string | optional, left out when empty | Why it is not working, in the runner's words. |
createdAt | string | required | A time, as RFC 3339. |
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"sourceRoot": "example",
"sourceRootName": "example",
"sourcePath": "projects/rush",
"destination": "example",
"schedule": "example",
"enabled": true,
"destKind": "example",
"createdAt": "2026-10-05T18:00:00Z"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
DELETE /api/v1/sync-jobs/{id}
Remove one.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Success. 200.
The reply has no body.
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
POST /api/v1/sync-jobs/{id}/dry-run
What a run would change. Reads both sides and writes nothing, so it needs no license.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. None.
Success. 200.
| Field | Type | Meaning | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
add | integer | required | |||||||||||||||||
change | integer | required | |||||||||||||||||
current | integer | required | |||||||||||||||||
bytes | integer | required | Size in bytes. | ||||||||||||||||
sample | array of objects | required | Up to [PLAN_SAMPLE] entries, each add or change. | ||||||||||||||||
Each item is an object:
| |||||||||||||||||||
truncated | boolean | required | True when the walk hit its ceiling, so the counts are a floor and the screen must not present them as the whole picture. | ||||||||||||||||
delete | integer | required | Always zero, and present so the screen can say so. Deletes are not mirrored at all; see the module note. | ||||||||||||||||
{
"add": 1,
"change": 1,
"current": 1,
"bytes": 1048576,
"sample": [
{
"path": "projects/rush",
"what": "2026-10-05T18:00:00Z",
"bytes": 1048576
}
],
"truncated": true,
"delete": 1
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | the source or the destination could not be read |
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "bad_request",
"message": "the source or the destination could not be read"
}
}
POST /api/v1/sync-jobs/{id}/run
Run it now rather than at its next scheduled time.
Who. An administrator, with a key that has the admin scope. An administrator's key that does not have that scope is refused. The key needs a license that includes the REST API. This call can also answer 402 when this installation's license does not cover automation.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. None.
Success. 200.
JSON object.
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | {e:#} |
| 402 | licence_required | this installation's license does not cover automation |
| 404 | not_found | not there, or not visible to this caller |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
{
"error": {
"code": "bad_request",
"message": "{e:#}"
}
}
Event rules
GET /api/v1/rules
Your event rules, and the ready-made ones to start from.
Who. Any user with a key that has the read scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
An event rule waits for something to happen on the server, such as a file arriving or a transfer failing, and runs steps in response. Event rules need the automation feature; in Free mode one rule runs at no charge. An administrator sees every rule; everyone else sees their own. Besides the rules the reply says whether this license includes automation (included), how many more rules Free mode can run (freeJobsLeft), whether the caller may save a step that runs a command (mayUseCommands, administrators only), and whether webhooks to private addresses are allowed.
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
rules | array of objects | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
templates | array of objects | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
included | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
freeJobsLeft | integer | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
mayUseCommands | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
allowPrivateWebhooks | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{
"rules": [
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"trigger": "example",
"triggerConfig": {
"stableSecs": 1,
"cron": "example",
"everyMinutes": 1,
"dailyAt": "2026-10-05T18:00:00Z",
"weekdays": [
1
]
},
"conditions": [
{
"kind": {},
"field": "example",
"value": "example"
}
],
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
],
"enabled": true,
"hasCommand": true,
"notifyOwnerOnFailure": true,
"maxConcurrent": 1,
"secretNames": [
"a-secret-shown-once"
],
"createdAt": "2026-10-05T18:00:00Z"
}
],
"templates": [
{
"id": "k7Qm2sLp9vX4aB1c",
"title": "example",
"what": "2026-10-05T18:00:00Z",
"needs": "example",
"rule": {
"name": "Rush delivery",
"trigger": "example",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
]
}
}
],
"included": true,
"freeJobsLeft": 1,
"mayUseCommands": true,
"allowPrivateWebhooks": true
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}
POST /api/v1/rules
Make an event rule.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API. This call can also answer 402 when this server's license has no room for another automation job.
The reply is the rule and its webhookSecret, the key a receiver checks webhook calls with; it can be shown again later with the signing key call. Values a step needs, such as a token, go in secrets once and are never returned; steps read them as {{secret.name}}. Only an administrator can save a rule with a step that runs a command. The rule starts at once unless enabled is false, and takes one of the jobs the license allows.
Request body. JSON.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
name | string | required | The name. | ||||||||||||||||||||||||||||||||
trigger | string | required | |||||||||||||||||||||||||||||||||
triggerConfig | TriggerConfig | optional, left out when empty | |||||||||||||||||||||||||||||||||
It is an object:
| |||||||||||||||||||||||||||||||||||
conditions | array of RuleCondition | optional, left out when empty | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
steps | array of objects | required | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
enabled | boolean | optional, left out when empty | |||||||||||||||||||||||||||||||||
notifyOwnerOnFailure | boolean | optional, left out when empty | |||||||||||||||||||||||||||||||||
maxConcurrent | integer | optional, left out when empty | |||||||||||||||||||||||||||||||||
secrets | BTreeMap<String, String> | optional, left out when empty | Written once; never read back. | ||||||||||||||||||||||||||||||||
{
"name": "Rush delivery",
"trigger": "example",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
]
}
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
rule | object | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
It is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
webhookSecret | string | required | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{
"rule": {
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"trigger": "example",
"triggerConfig": {
"stableSecs": 1,
"cron": "example",
"everyMinutes": 1,
"dailyAt": "2026-10-05T18:00:00Z",
"weekdays": [
1
]
},
"conditions": [
{
"kind": {},
"field": "example",
"value": "example"
}
],
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
],
"enabled": true,
"hasCommand": true,
"notifyOwnerOnFailure": true,
"maxConcurrent": 1,
"secretNames": [
"a-secret-shown-once"
],
"createdAt": "2026-10-05T18:00:00Z"
},
"webhookSecret": "a-secret-shown-once"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | no name or one over 100 characters, an unknown trigger, a schedule that cannot work, a condition or step that is not valid (no steps, more than 20, a name used twice, a required setting missing, or a delete step without `confirmed`), a secret name or value that is not allowed, or `maxConcurrent` outside 1 to 8 |
| 402 | licence_required | this server's license has no room for another automation job |
| 403 | forbidden | a step runs a command and the caller is not an administrator |
| 409 | conflict | a rule with that name already exists |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
{
"error": {
"code": "bad_request",
"message": "no name or one over 100 characters, an unknown trigger, a schedule that cannot work, a condition or step that is not valid (no steps, more than 20, a name used twice, a required setting missing, or a delete step without `confirmed`), a secret name or value that is not allowed, or `maxConcurrent` outside 1 to 8"
}
}
GET /api/v1/rules/runs
Past runs of event rules, newest first.
Who. Any user with a key that has the read scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
Up to 200 runs, each step's output shortened; fetch one run for the rest. Secrets are replaced by ***. An administrator sees every run; everyone else sees the runs of their own rules.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
rule | query | string | optional | Only this rule's runs. |
state | query | string | optional | queued, running, done, failed, skipped or interrupted. |
from | query | string | optional | RFC 3339, inclusive. |
to | query | string | optional | RFC 3339, exclusive. |
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
runs | array of objects | required | The runs, newest first, up to 200. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{
"runs": [
{
"id": "k7Qm2sLp9vX4aB1c",
"ruleId": "k7Qm2sLp9vX4aB1c",
"ruleName": "example",
"state": "active",
"startedBy": "example",
"conditionsPassed": true,
"dryRun": false,
"startedAt": "2026-10-05T18:00:00Z",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"state": "active",
"attempts": 1,
"output": "example"
}
]
}
]
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | a date that is not written like 2031-03-04T10:00:00Z |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "bad_request",
"message": "a date that is not written like 2031-03-04T10:00:00Z"
}
}
GET /api/v1/rules/runs/{id}
One run of an event rule, with the output of every step.
Who. Any user with a key that has the read scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
The last 64 KB of each step's output is kept, with every secret replaced by ***. For a dry run each step also has a plan: what it would have done.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleId | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleName | string | required | |||||||||||||||||||||||||||||||||||||||||||||
eventId | string | optional | The id. | ||||||||||||||||||||||||||||||||||||||||||||
state | string | required | Where this record is in its life. | ||||||||||||||||||||||||||||||||||||||||||||
startedBy | string | required | |||||||||||||||||||||||||||||||||||||||||||||
conditionsPassed | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
dryRun | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
error | string | optional | |||||||||||||||||||||||||||||||||||||||||||||
startedAt | string | required | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
finishedAt | string | optional | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
steps | array of objects | required | |||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||
{
"id": "k7Qm2sLp9vX4aB1c",
"ruleId": "k7Qm2sLp9vX4aB1c",
"ruleName": "example",
"state": "active",
"startedBy": "example",
"conditionsPassed": true,
"dryRun": false,
"startedAt": "2026-10-05T18:00:00Z",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"state": "active",
"attempts": 1,
"output": "example"
}
]
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | no such run, or it belongs to someone else's rule |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
POST /api/v1/rules/runs/{id}/rerun
Run a past run again.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
Queues a new run of the same rule with the event the old run kept, even if the event itself has since been cleared away. The conditions are not checked again. The old run stays as it was.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. None.
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleId | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleName | string | required | |||||||||||||||||||||||||||||||||||||||||||||
eventId | string | optional | The id. | ||||||||||||||||||||||||||||||||||||||||||||
state | string | required | Where this record is in its life. | ||||||||||||||||||||||||||||||||||||||||||||
startedBy | string | required | |||||||||||||||||||||||||||||||||||||||||||||
conditionsPassed | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
dryRun | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
error | string | optional | |||||||||||||||||||||||||||||||||||||||||||||
startedAt | string | required | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
finishedAt | string | optional | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
steps | array of objects | required | |||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||
{
"id": "k7Qm2sLp9vX4aB1c",
"ruleId": "k7Qm2sLp9vX4aB1c",
"ruleName": "example",
"state": "active",
"startedBy": "example",
"conditionsPassed": true,
"dryRun": false,
"startedAt": "2026-10-05T18:00:00Z",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"state": "active",
"attempts": 1,
"output": "example"
}
]
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 403 | forbidden | the rule runs a command and the caller is not an administrator |
| 404 | not_found | no such run, or it belongs to someone else's rule |
| 409 | conflict | the rule is paused; the message says why |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "forbidden",
"message": "you do not have access to this"
}
}
PATCH /api/v1/rules/{id}
Change an event rule.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API. This call can also answer 402 when switching it on, when this server's license has no room for another automation job.
Send only what changes. A secret sent with an empty value is removed, and one left out is kept. Switching a rule on takes one of the license's jobs; editing it or switching it off does not. Only an administrator can add a command step, or edit a rule that already has one other than switching it off.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. JSON.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
name | string | optional | The name. | ||||||||||||||||||||||||||||||||
trigger | string | optional | |||||||||||||||||||||||||||||||||
triggerConfig | TriggerConfig | optional | |||||||||||||||||||||||||||||||||
It is an object:
| |||||||||||||||||||||||||||||||||||
conditions | array of RuleCondition | optional | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
steps | array of StepInput | optional | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
enabled | boolean | optional | |||||||||||||||||||||||||||||||||
notifyOwnerOnFailure | boolean | optional | |||||||||||||||||||||||||||||||||
maxConcurrent | integer | optional | |||||||||||||||||||||||||||||||||
secrets | BTreeMap<String, String> | optional | |||||||||||||||||||||||||||||||||
{
"name": "Rush delivery",
"trigger": "example",
"triggerConfig": {
"stableSecs": 1,
"cron": "example",
"everyMinutes": 1,
"dailyAt": "2026-10-05T18:00:00Z",
"weekdays": [
1
]
},
"conditions": [
{
"kind": {},
"field": "example",
"value": "example"
}
],
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
],
"enabled": true,
"notifyOwnerOnFailure": true,
"maxConcurrent": 1
}
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | string | required | The id. | ||||||||||||||||||||||||||||||||
name | string | required | The name. | ||||||||||||||||||||||||||||||||
ownerId | string | optional | The id. | ||||||||||||||||||||||||||||||||
ownerEmail | string | optional | An email address. | ||||||||||||||||||||||||||||||||
trigger | string | required | |||||||||||||||||||||||||||||||||
triggerConfig | object | required | |||||||||||||||||||||||||||||||||
It is an object:
| |||||||||||||||||||||||||||||||||||
conditions | array of objects | required | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
steps | array of objects | required | |||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||
enabled | boolean | required | |||||||||||||||||||||||||||||||||
pausedReason | string | optional | |||||||||||||||||||||||||||||||||
hasCommand | boolean | required | |||||||||||||||||||||||||||||||||
notifyOwnerOnFailure | boolean | required | |||||||||||||||||||||||||||||||||
maxConcurrent | integer | required | |||||||||||||||||||||||||||||||||
secretNames | array of string | required | Names only. The values are never sent back. | ||||||||||||||||||||||||||||||||
lastRunAt | string | optional | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||
nextRunAt | string | optional | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||
createdAt | string | required | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||
{
"id": "k7Qm2sLp9vX4aB1c",
"name": "Rush delivery",
"trigger": "example",
"triggerConfig": {
"stableSecs": 1,
"cron": "example",
"everyMinutes": 1,
"dailyAt": "2026-10-05T18:00:00Z",
"weekdays": [
1
]
},
"conditions": [
{
"kind": {},
"field": "example",
"value": "example"
}
],
"steps": [
{
"name": "Rush delivery",
"kind": {},
"config": {
"file": {
"name": "rush.mov"
}
},
"retries": 1,
"onFailure": {},
"timeoutSecs": 1,
"confirmed": true
}
],
"enabled": true,
"hasCommand": true,
"notifyOwnerOnFailure": true,
"maxConcurrent": 1,
"secretNames": [
"a-secret-shown-once"
],
"createdAt": "2026-10-05T18:00:00Z"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | any of the refusals for making a rule |
| 402 | licence_required | switching it on, when this server's license has no room for another automation job |
| 403 | forbidden | the change adds or edits a command step and the caller is not an administrator |
| 404 | not_found | no such rule, or it is someone else's |
| 409 | conflict | a rule with that name already exists |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
{
"error": {
"code": "bad_request",
"message": "any of the refusals for making a rule"
}
}
DELETE /api/v1/rules/{id}
Delete an event rule.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
The rule stops at once and gives its job back. Needs the write scope rather than delete, like every other change to a rule.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Success. 200.
The reply has no body.
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | no such rule, or it is someone else's |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
GET /api/v1/rules/{id}/signing-key
Show the key a rule's webhook receivers check.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
Only to the rule's owner or an administrator, and each time it is read is written to the audit log. It is a call of its own so that the rule itself, which is listed and cached, never carries it.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Success. 200.
| Field | Type | Meaning | |
|---|---|---|---|
signingKey | string | required |
{
"signingKey": "example"
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 404 | not_found | no such rule, or it is someone else's |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "not_found",
"message": "not found"
}
}
POST /api/v1/rules/{id}/run
Run an event rule now, for real or as a dry run.
Who. Any user with a key that has the write scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
With eventId the rule runs against that past event from the events list; without one, against a made-up event of the rule's kind. A dry run shows what each step would do and does none of it, and the reply comes when it has finished. A real run is queued, so the reply may still say queued or running; read the run again to follow it. If the event does not meet the rule's conditions the run is recorded as skipped. A paused rule can be dry-run but not run, and only an administrator can run a rule that has a command step for real.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
id | path | string | required | The resource's id. |
Request body. JSON.
The body may be left out.
| Field | Type | Meaning | |
|---|---|---|---|
eventId | string | optional | The id. |
dryRun | boolean | optional |
{
"eventId": "k7Qm2sLp9vX4aB1c",
"dryRun": false
}
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleId | string | required | The id. | ||||||||||||||||||||||||||||||||||||||||||||
ruleName | string | required | |||||||||||||||||||||||||||||||||||||||||||||
eventId | string | optional | The id. | ||||||||||||||||||||||||||||||||||||||||||||
state | string | required | Where this record is in its life. | ||||||||||||||||||||||||||||||||||||||||||||
startedBy | string | required | |||||||||||||||||||||||||||||||||||||||||||||
conditionsPassed | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
dryRun | boolean | required | |||||||||||||||||||||||||||||||||||||||||||||
error | string | optional | |||||||||||||||||||||||||||||||||||||||||||||
startedAt | string | required | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
finishedAt | string | optional | A time, as RFC 3339. | ||||||||||||||||||||||||||||||||||||||||||||
steps | array of objects | required | |||||||||||||||||||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||||||||||||||||||
{
"id": "k7Qm2sLp9vX4aB1c",
"ruleId": "k7Qm2sLp9vX4aB1c",
"ruleName": "example",
"state": "active",
"startedBy": "example",
"conditionsPassed": true,
"dryRun": false,
"startedAt": "2026-10-05T18:00:00Z",
"steps": [
{
"name": "Rush delivery",
"kind": {},
"state": "active",
"attempts": 1,
"output": "example"
}
]
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 400 | bad_request | the event is no longer kept |
| 403 | forbidden | the rule runs a command and the caller is not an administrator |
| 404 | not_found | no such rule, or it is someone else's |
| 409 | conflict | the rule is paused; the message says why |
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "bad_request",
"message": "the event is no longer kept"
}
}
Events
GET /api/v1/events
Past events, to test a rule against.
Who. Any user with a key that has the read scope. A key with the admin scope includes the others. The key needs a license that includes the REST API.
Newest first, of the kind asked for or of every kind, up to 200. Events name files and the addresses of the people who sent them, across every folder, so only an administrator is shown any; everyone else gets an empty list instead of an error, which keeps the test screen working with a made-up event.
Parameters.
| Name | In | Type | Meaning | |
|---|---|---|---|---|
kind | query | string | optional | Only events of this trigger kind, such as file.arrived. |
limit | query | integer | optional | 1 to 200. Default 50. Clamped, not refused. |
Success. 200.
| Field | Type | Meaning | |||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
events | array of objects | required | Newest first. Empty for anyone who is not an administrator. | ||||||||||||||||||||||||||||
Each item is an object:
| |||||||||||||||||||||||||||||||
{
"events": [
{
"id": "k7Qm2sLp9vX4aB1c",
"kind": "file.arrived",
"at": "2026-10-05T18:00:00Z",
"path": "projects/rush",
"actorEmail": "[email protected]",
"body": {
"file": {
"name": "rush.mov"
}
}
}
]
}
Errors. The body always has the shape in Errors. Match on code.
| Status | code | When |
|---|---|---|
| 401 | unauthenticated | no key, or a key that is unknown, expired, revoked, or owned by a disabled account |
| 403 | forbidden | the key is valid but does not have the scope, or an administrator route was called by someone who is not an administrator |
| 402 | licence_required | the license does not include the REST API |
{
"error": {
"code": "unauthenticated",
"message": "sign in to continue"
}
}