Update the monitor

Embed
Preview of the card
<a href="https://forumulate.com/reference/forumulate-api-status-updatemonitor"><img src="https://forumulate.com/reference/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/8042f004-e3d9-445f-b7a4-b6c1f86836e6/pages/3275113c-33e1-4414-9dce-5a8455e02ee9/social-card.svg?v=3e7ae33eec8b" alt="Update the monitor" width="600" height="315"></a>
PATCHhttps://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}

Changes one status check in place — its target, its interval, its thresholds, whether it is paused. Pause rather than delete during planned work, so the uptime history and the heartbeat URL survive.

Requires token scope: write (the coarse method gate) for Atlas key (ak_), Personal Access Token (cft_) or OAuth (cfo_) auth — in addition to any catalog scope (GET /pats/scopes) the route’s capability needs. Session/cookie auth is governed by RBAC capabilities instead.

Parameters
orgIdstringpathrequired
spaceIdstringpathrequired
monitorIdstringpathrequired
forumulate-versionstringheader
API version negotiation. Send forumulate-version: 2026-12-01 on every request from a new integration; it is optional only so that integrations written before versioning keep working. Each version includes everything before it:
Idempotency-Keystringheader
Makes this write safe to retry. Optional — send any unique string (a UUID is ideal) and the first request runs while its response is remembered under that key for 24 hours; an identical retry replays that same status and body instead of acting twice, so a timeout or a 5xx from the edge can be retried without creating a second row. A retry sent while the first request is still in flight is refused with 409. The key is scoped to the method and path, so the same key on a different endpoint is a different request. Error responses of 5xx are never cached — those retries re-run. A key is bound to the BODY it was first used with: reusing it with a different body is a 409 idempotency.key_reused, not a replay, because replaying would tell you a write landed that never ran. Generate one key per request, never per process or per session.
Request body application/json
namestring
urlstring
methodstring
GET | HEAD | POST
kindstring
http (default) polls url; heartbeat waits for your job to ping; manual is probed by nothing — its state is declaredState (else operational) or what an open incident linked to it says; space rolls up another status page of this organization (targetSpaceId) on a hub page; statuspage mirrors a vendor’s public Statuspage (url, plus vendorComponent). Fixed at creation: a PATCH cannot turn one kind into another — delete and re-create instead.
http | heartbeat | manual | space | statuspage
targetSpaceIdstring
Kind space: the status page it rolls up (state, uptime and days are that page’s).
vendorComponentstring
Kind statuspage: the vendor component’s id or exact name in its summary.json. Null: the vendor page’s overall indicator.
regionstring
Where it runs ("EU", "US-East"). theme.status.components.groupBy: region groups by it.
descriptionstring
What the component is, in a sentence — shown to readers beside its name.
slugstring
Its stable address within the page (component page, per-component subscription), normalised to lowercase words joined by hyphens. Minted from the name on create when omitted; unique per page — a taken one is a 409. Renaming the component does not move it.
linkUrlstring
Where the component’s own docs or product live; its name links there.
displaystring
bars (default) draws its day bars; status only its state; hidden-unless-degraded leaves it off the page while it is operational.
bars | status | hidden-unless-degraded
startsOnstring
The day it started existing. Earlier days draw as "not yet" rather than as no data. Null: from its first check (a manual component: from the day it was created).
intervalSecondsinteger
Seconds between checks (http, clamped to 30–3600, default 60) or the longest wait for a ping (heartbeat, clamped to 60–604800, default 3600). PATCH clamps by the same rule.
visibleboolean
alertsEnabledboolean
failureThresholdinteger
successThresholdinteger
keywordstring
certExpiryDaysinteger
expectStatusinteger
maxLatencyMsinteger
requestHeadersobject
requestBodystring
bodyPathstring
bodyExpectstring
groupstring
audienceobject
Who may see this on the public page: everyone (default), signedIn (any signed-in reader) or groups (a signed-in member of one of groups). Hidden rows are dropped by the API before anything is sent. The machine doors — summary.json, api/v2, the feeds, the badge and the widget — always answer as an anonymous reader.
Show child parameters
whostringrequired
everyone | signedIn | groups
groupsstring[]
= []
declaredStatestring
A state a person declares, which wins over the checks until it is cleared with null. Every field of this body — this one, alertsEnabled and both thresholds included — is applied on create exactly as on PATCH.
{
  "name": "string",
  "url": "",
  "method": "GET",
  "kind": "http",
  "targetSpaceId": "string",
  "vendorComponent": "string",
  "region": "string",
  "description": "string",
  "slug": "string",
  "linkUrl": "string",
  "display": "bars",
  "startsOn": "string",
  "intervalSeconds": 0,
  "visible": true,
  "alertsEnabled": true,
  "failureThreshold": 0,
  "successThreshold": 0,
  "keyword": "string",
  "certExpiryDays": 0,
  "expectStatus": 0,
  "maxLatencyMs": 0,
  "requestHeaders": {},
  "requestBody": "string",
  "bodyPath": "string",
  "bodyExpect": "string",
  "group": "string",
  "audience": {
    "who": "everyone",
    "groups": []
  },
  "declaredState": "operational"
}
Code samples
cURL
curl -X PATCH "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}" \
  -H "forumulate-version: <value>" \
  -H "Idempotency-Key: <value>" \
  -H "Content-Type: application/json" \
  -d '{"name":"string","url":"","method":"GET","kind":"http","targetSpaceId":"string","vendorComponent":"string","region":"string","description":"string","slug":"string","linkUrl":"string","display":"bars","startsOn":"string","intervalSeconds":0,"visible":true,"alertsEnabled":true,"failureThreshold":0,"successThreshold":0,"keyword":"string","certExpiryDays":0,"expectStatus":0,"maxLatencyMs":0,"requestHeaders":{},"requestBody":"string","bodyPath":"string","bodyExpect":"string","group":"string","audience":{"who":"everyone","groups":[]},"declaredState":"operational"}'
TypeScript
const res = await fetch('https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}', {
  method: 'PATCH',
  headers: {
    'forumulate-version': '<value>',
    'Idempotency-Key': '<value>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({"name":"string","url":"","method":"GET","kind":"http","targetSpaceId":"string","vendorComponent":"string","region":"string","description":"string","slug":"string","linkUrl":"string","display":"bars","startsOn":"string","intervalSeconds":0,"visible":true,"alertsEnabled":true,"failureThreshold":0,"successThreshold":0,"keyword":"string","certExpiryDays":0,"expectStatus":0,"maxLatencyMs":0,"requestHeaders":{},"requestBody":"string","bodyPath":"string","bodyExpect":"string","group":"string","audience":{"who":"everyone","groups":[]},"declaredState":"operational"}),
});
const data = await res.json();
Python
import requests

res = requests.request(
    "PATCH",
    "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}",
    headers={
    "forumulate-version": "<value>",
    "Idempotency-Key": "<value>",
    "Content-Type": "application/json",
    },
    json={"name": "string", "url": "", "method": "GET", "kind": "http", "targetSpaceId": "string", "vendorComponent": "string", "region": "string", "description": "string", "slug": "string", "linkUrl": "string", "display": "bars", "startsOn": "string", "intervalSeconds": 0, "visible": True, "alertsEnabled": True, "failureThreshold": 0, "successThreshold": 0, "keyword": "string", "certExpiryDays": 0, "expectStatus": 0, "maxLatencyMs": 0, "requestHeaders": {}, "requestBody": "string", "bodyPath": "string", "bodyExpect": "string", "group": "string", "audience": {"who": "everyone", "groups": []}, "declaredState": "operational"},
)
data = res.json()
Go
package main

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func main() {
	req, _ := http.NewRequest("PATCH", "https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}", strings.NewReader(`{"name":"string","url":"","method":"GET","kind":"http","targetSpaceId":"string","vendorComponent":"string","region":"string","description":"string","slug":"string","linkUrl":"string","display":"bars","startsOn":"string","intervalSeconds":0,"visible":true,"alertsEnabled":true,"failureThreshold":0,"successThreshold":0,"keyword":"string","certExpiryDays":0,"expectStatus":0,"maxLatencyMs":0,"requestHeaders":{},"requestBody":"string","bodyPath":"string","bodyExpect":"string","group":"string","audience":{"who":"everyone","groups":[]},"declaredState":"operational"}`))
	req.Header.Set("forumulate-version", "<value>")
	req.Header.Set("Idempotency-Key", "<value>")
	req.Header.Set("Content-Type", "application/json")
	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
PHP
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['forumulate-version: <value>', 'Idempotency-Key: <value>', 'Content-Type: application/json']);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"name":"string","url":"","method":"GET","kind":"http","targetSpaceId":"string","vendorComponent":"string","region":"string","description":"string","slug":"string","linkUrl":"string","display":"bars","startsOn":"string","intervalSeconds":0,"visible":true,"alertsEnabled":true,"failureThreshold":0,"successThreshold":0,"keyword":"string","certExpiryDays":0,"expectStatus":0,"maxLatencyMs":0,"requestHeaders":{},"requestBody":"string","bodyPath":"string","bodyExpect":"string","group":"string","audience":{"who":"everyone","groups":[]},"declaredState":"operational"}');
$response = curl_exec($ch);
curl_close($ch);
echo $response;
Ruby
require 'net/http'
require 'uri'

uri = URI('https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}')
req = Net::HTTP::Patch.new(uri)
req['forumulate-version'] = '<value>'
req['Idempotency-Key'] = '<value>'
req['Content-Type'] = 'application/json'
req.body = '{"name":"string","url":"","method":"GET","kind":"http","targetSpaceId":"string","vendorComponent":"string","region":"string","description":"string","slug":"string","linkUrl":"string","display":"bars","startsOn":"string","intervalSeconds":0,"visible":true,"alertsEnabled":true,"failureThreshold":0,"successThreshold":0,"keyword":"string","certExpiryDays":0,"expectStatus":0,"maxLatencyMs":0,"requestHeaders":{},"requestBody":"string","bodyPath":"string","bodyExpect":"string","group":"string","audience":{"who":"everyone","groups":[]},"declaredState":"operational"}'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') do |http|
  http.request(req)
end
puts res.body
Java
import java.net.URI;
import java.net.http.*;
import java.net.http.HttpRequest.BodyPublishers;

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://forumulate.com/api/orgs/{orgId}/spaces/{spaceId}/status/monitors/{monitorId}"))
    .header("forumulate-version", "<value>")
    .header("Idempotency-Key", "<value>")
    .header("Content-Type", "application/json")
    .method("PATCH", BodyPublishers.ofString("{\"name\":\"string\",\"url\":\"\",\"method\":\"GET\",\"kind\":\"http\",\"targetSpaceId\":\"string\",\"vendorComponent\":\"string\",\"region\":\"string\",\"description\":\"string\",\"slug\":\"string\",\"linkUrl\":\"string\",\"display\":\"bars\",\"startsOn\":\"string\",\"intervalSeconds\":0,\"visible\":true,\"alertsEnabled\":true,\"failureThreshold\":0,\"successThreshold\":0,\"keyword\":\"string\",\"certExpiryDays\":0,\"expectStatus\":0,\"maxLatencyMs\":0,\"requestHeaders\":{},\"requestBody\":\"string\",\"bodyPath\":\"string\",\"bodyExpect\":\"string\",\"group\":\"string\",\"audience\":{\"who\":\"everyone\",\"groups\":[]},\"declaredState\":\"operational\"}"))
    .build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
Responses
200 Success.
Example
{
  "monitor": {
    "alertsEnabled": true,
    "audience": {
      "groups": [
        "string"
      ],
      "who": "everyone"
    },
    "bodyExpect": "string",
    "bodyPath": "string",
    "certExpiryDays": 0,
    "declaredState": "degraded",
    "description": "string",
    "display": "bars",
    "expectStatus": 0,
    "failureThreshold": 0,
    "group": "string",
    "id": "string",
    "intervalSeconds": 0,
    "keyword": "string",
    "kind": "heartbeat",
    "lastPingAt": "string",
    "lastPingDetail": "string",
    "lastPingState": "degraded",
    "linkUrl": "string",
    "maxLatencyMs": 0,
    "method": "string",
    "name": "string",
    "pingUrl": "string",
    "region": "string",
    "requestBody": "string",
    "requestHeaderNames": [
      "string"
    ],
    "slug": "string",
    "startsOn": "string",
    "successThreshold": 0,
    "targetSpaceId": "string",
    "url": "string",
    "vendorCheckedAt": "string",
    "vendorComponent": "string",
    "vendorState": "degraded",
    "visible": true
  },
  "warnings": [
    "tags: \"Launch Day\" is stored as \"launch-day\""
  ]
}
Schema
monitorobjectrequired
Show child parameters
alertsEnabledbooleanrequired
audienceobject
Show child parameters
groupsstring[]required
whostringrequired
everyone | groups | signedIn
bodyExpectstringrequired
bodyPathstringrequired
certExpiryDaysnumberrequired
declaredStatestringrequired
degraded | maintenance | major_outage | operational | partial_outage
descriptionstringrequired
displaystringrequired
bars | hidden-unless-degraded | status
expectStatusnumberrequired
failureThresholdnumberrequired
groupstringrequired
idstringrequired
intervalSecondsnumberrequired
keywordstringrequired
kindstringrequired
heartbeat | http | manual | space | statuspage
lastPingAtstring
lastPingDetailstring
lastPingStatestring
degraded | major_outage | partial_outage
linkUrlstringrequired
maxLatencyMsnumberrequired
methodstringrequired
namestringrequired
pingUrlstring
regionstringrequired
requestBodystringrequired
requestHeaderNamesstring[]required
slugstringrequired
startsOnstringrequired
successThresholdnumberrequired
targetSpaceIdstring
urlstringrequired
vendorCheckedAtstring
vendorComponentstring
vendorStatestring
degraded | maintenance | major_outage | operational | partial_outage
visiblebooleanrequired
warningsstring[]
Values we ACCEPTED and then rewrote, one sentence each — a slugified tag, a normalised colour, a clamped range, a slug that was taken. Absent when nothing was rewritten, never []. The same sentences are on the X-Field-Warnings response header. If this is present, something you sent is not what is stored; read the resource back rather than assuming your own value.
400 The request could not be understood — a malformed header, path or query value (request.malformed). A value that was understood but is not acceptable is a 422 validation.failed.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
401 No credential, or one that is expired or revoked (auth.required). Send a Bearer token or the session cookie.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
403 Authenticated, and not allowed — always rbac.forbidden, whether what is missing is the capability, the token scope, or a resource the token is pinned away from. The message names the capability and, for a scope refusal, the scopes that would grant it. A refusal because of the PLAN is a 402 with quota.exceeded, not this.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
404 No such thing — one of the ids in the path does not resolve, or resolves to something this caller may not see (*.not_found).
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
409 Refused because of the state this already is in — a name or slug already taken, a resource that already exists, or a precondition on the thing itself (conflict, *.taken, *.exists). Unlike a 422 the body is fine; unlike a 503 retrying it unchanged will not help.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
422 The body was understood and a value is unacceptable (validation.failed). error.details names the field paths.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
429 Rate limited — see the RateLimit-* headers.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
default Error — the stable { error: { code, message } } envelope.
Example
{
  "error": {
    "code": "string",
    "message": "string",
    "details": {},
    "docs": "string",
    "reason": "string",
    "slugs": [
      "string"
    ],
    "conflict": {
      "etag": "string",
      "ops": [
        null
      ]
    }
  },
  "requestId": "string"
}
Schema
errorobjectrequired
Show child parameters
codestringrequired
Stable, machine-readable error code, e.g. rbac.forbidden.
messagestringrequired
Human-readable explanation.
detailsobject
Field-level validation problems, keyed by field path (422 only).
docsstring
Where the vocabulary or format this error is about is published — an absolute URL, or an API route such as GET /space-types/{type}/presets. Present on errors over a controlled list, so the answer to "what am I allowed to send?" is in the error itself.
reasonstring
Why a credential was refused, as one stable word, where one status has several causes — e.g. an external_jwt redeem answers iat_too_old, iat_in_future, bad_signature, bad_issuer, bad_audience, expired and more. Branch on this, not on message.
slugsstring[]
The exact slugs that collided, on a slug-conflict 409 — space.slug_taken, page.slug_taken, collection.slug_taken, site.slug_taken or badge.slug_taken.
conflictobject
On a 409 from a content entry field write (PATCH …/entries/{entryId}/fields) whose If-Match was stale.
Show child parameters
etagstringrequired
The entry's current fields etag.
opsarrayrequired
The field operations since your If-Match that touch a path your own operations touch. Empty: none did — retry the batch unchanged under etag. null: the history no longer reaches your tag — re-read the entry first.
requestIdstring
The id of this request — the same value as the x-request-id and x-forumulate-request-id response headers. Quote it in a bug report: it is the only thing that finds your exact request in our logs. It is in the body because that is the part that survives — an SDK that throws the parsed body, a serverless log that keeps the body and drops the headers, a ticket with the JSON pasted in.
The Forumulate teamUpdated