Download OpenAPI specification:
Muster L1 API
Spec-first contract of Muster L1: alert grouping and on-call after Alertmanager.
Listeners. Operations are served by one of three listeners, marked x-listener: app (UI and API, the default server), ingest (ingestion, Heartbeat, messenger callbacks; the address for machines) and internal (health and metrics). When two listeners share an address, both are served on that one port.
Permissions. Every operation lists the Permission it needs in x-permission (<resource>:<verb>; see the Permission schema for the Role matrix), or one of authenticated (any signed-in identity), integration-token or none. A Personal access token can only narrow its owner's Permissions.
Credentials. Operations that change the caller's own account (profile, password, TOTP, Personal access tokens, Account links, sessions) accept the web session with its CSRF token only; a token gets 403 (session_required). Service account tokens get 403 (service_account_not_allowed) on the reads under /me.
Conventions. Resources are plural kebab-case nouns and URLs use the opaque public_id. Lists use cursor pagination (cursor, limit default 50, maximum 500; the response carries next_cursor) and filters as query parameters. Errors are RFC 9457 application/problem+json (Problem; the stable codes are catalogued in x-problem-codes). An operation that this build does not implement yet answers 501 (not-implemented). Configuration resources return an ETag header and an etag field; updates are PUT with If-Match and fail with 412 on a mismatch, 428 without it. On an update an omitted optional field keeps its stored value and an explicit null clears it. A natural-key conflict is 409. Rate limits answer 429 with Retry-After. Times are RFC 3339 in UTC; durations are integer seconds in fields named *_seconds (retention periods are whole days in *_days, measured latencies are milliseconds in *_ms). Enum values are snake_case; kebab-case is kept for URL segments, problem types and the type of live-update hints. Secret fields are write-only; reads show *_status objects with set and updated_at.
Not validated by the spec. The ingestion endpoints accept any body up to the size limit and store it as received; they are excluded from request validation (see ingestSnapshot).
During 0.x breaking changes are allowed; from 1.0 /api/v1 is stable and a removal is announced one minor release in advance.
Sign in with a local account or OIDC, the second factor, sessions, password setup. Public sign-in operations need no credentials. A session can be limited: while state is totp_required or totp_enrolment_required only the operations named in Session work; others answer 403 with the same code.
Whether the sign-in page shows the OIDC button next to the local form. Local sign-in is always available; no setting turns it off. Carries no version or other detail about the installation.
{- "oidc": {
- "enabled": true,
- "display_name": "string"
}
}Creates a session cookie (HttpOnly; Secure; SameSite=Lax) and returns the CSRF token. If the user has TOTP and the request carries neither totp_code nor recovery_code, the session starts in the state totp_required and POST /sessions/current/totp completes it. Under a TOTP policy that covers a user without TOTP the state is totp_enrolment_required. A wrong login, password or code is 401 (invalid_credentials) without saying which one was wrong. Failed attempts slow down per account and per source address (429 with Retry-After). A request a browser marks as cross-site (Sec-Fetch-Site set to cross-site) is refused with 403 (csrf_invalid).
| login required | string Compared case-insensitively. |
| password required | string <password> |
| totp_code | string Current TOTP code, if the user has TOTP and wants to finish in one request. |
| recovery_code | string A single-use recovery code instead of |
{- "login": "string",
- "password": "pa$$word",
- "totp_code": "string",
- "recovery_code": "string"
}{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}, - "state": "active",
- "csrf_token": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "idle_expires_at": "2019-08-24T14:15:22Z",
- "method": "local",
- "permissions": [
- "alert-groups:read"
]
}Returns the session in any state, including the CSRF token the SPA sends on mutating requests.
{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}, - "state": "active",
- "csrf_token": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "idle_expires_at": "2019-08-24T14:15:22Z",
- "method": "local",
- "permissions": [
- "alert-groups:read"
]
}{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Completes a session in the state totp_required with a current TOTP code or a single-use recovery code; works the same after a local and an OIDC sign-in. A wrong code is 401 (invalid_credentials) and slows down like a wrong password; 409 (totp_not_pending) when the session is not waiting for a code.
| totp_code | string Current TOTP code. |
| recovery_code | string A single-use recovery code. |
{- "totp_code": "string"
}{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}, - "state": "active",
- "csrf_token": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "idle_expires_at": "2019-08-24T14:15:22Z",
- "method": "local",
- "permissions": [
- "alert-groups:read"
]
}Redirects the browser to the identity provider with PKCE (S256), state and nonce, all mandatory, requesting offline_access besides the configured scopes; when the IdP grants it, the offline token is stored on the user, encrypted, replacing the previous one. Muster exchanges the code itself through the back channel. The redirect URI to register at the identity provider is MUSTER_PUBLIC_URL/api/v1/sessions/oidc/callback. 409 (oidc_not_enabled) while OIDC is off.
| return_to | string Path to open after sign-in: a relative path that starts with a single |
{- "title": "Command refused",
- "status": 409,
- "detail": "A newer open Alert Group #415 exists.",
- "instance": "/api/v1/alert-groups/AGK7M3QX9P2RTA/unresolve",
- "code": "newer_alert_group_exists",
- "related_alert_group": {
- "id": "AGC71D0EH5MXQB",
- "number": 415
}
}Redirect target of the identity provider. Every outcome is a 302 to the SPA, so the browser never shows a raw error. On success it sets the session cookie (state active, or totp_required when the user has TOTP and the identity provider did not assert multi-factor authentication) and redirects to the return_to of the start or to /. The first sign-in of a new identity creates the user, with the login taken from preferred_username, else the email, else sub. Accounts are never merged by login or email; an identity reaches an existing account only by linking it from that account's profile (startOidcLink). A failure redirects to /sign-in?error=<code> with one of no_access (the person is in no mapped group; the Audit log records the groups from the claim), login_taken (a new identity's login belongs to an existing account; the page says "An account with this login already exists. Sign in with it and link OIDC in your profile.", and the Audit log records the refusal), account_disabled, oidc_disabled, invalid_request (bad or missing state, code or nonce) and idp_error (the identity provider or the back channel failed).
| code | string Authorization code. |
| state | string State issued by |
| error | string Error reported by the identity provider. |
{- "title": "Rate limited",
- "status": 429,
- "detail": "Too many requests for this token.",
- "instance": "/api/v1/alert-groups",
- "retry_after_seconds": 12
}Uses the single-use token of a password setup link (the link carries it in the URL fragment, so it reaches neither server logs nor referrers). The user is then asked to enrol TOTP if the policy requires it. An unknown token is 404; a token past auth.password_setup_link_ttl is 410 (link_expired); one already used or replaced by a newer link is 410 (link_used). Like the sign-in, a request that a browser marks as cross-site is 403 (csrf_invalid).
| token required | string The token from the setup link. |
| password required | string <password> At least |
{- "token": "string",
- "password": "pa$$word"
}{- "title": "Validation failed",
- "status": 400,
- "detail": "The request body is not valid.",
- "instance": "/api/v1/routes",
- "errors": [
- {
- "pointer": "/matchers/0/op",
- "code": "invalid_format",
- "detail": "op must be one of =, !=, =~, !~"
}
]
}The caller and the effective Permissions, narrowed by the token if one is used. Service account tokens get 403 (service_account_not_allowed).
{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}, - "permissions": [
- "alert-groups:read"
]
}Changes name, time zone and language. Web session only.
| name required | string non-empty |
| time_zone | string or null |
| language | string or null (NullableLanguage) Enum: "en" "ru" null UI or template language; null follows the default. |
{- "name": "string",
- "time_zone": "string",
- "language": "en"
}{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}, - "permissions": [
- "alert-groups:read"
]
}Ends all other sessions of the user. Local users only (409 local_user_only otherwise). Web session only.
| current_password required | string <password> |
| new_password required | string <password> At least |
{- "current_password": "pa$$word",
- "new_password": "pa$$word"
}{- "title": "Validation failed",
- "status": 400,
- "detail": "The request body is not valid.",
- "instance": "/api/v1/routes",
- "errors": [
- {
- "pointer": "/matchers/0/op",
- "code": "invalid_format",
- "detail": "op must be one of =, !=, =~, !~"
}
]
}Starts linking the caller's account to an identity at the OIDC provider: returns the authorization URL (PKCE S256, state and nonce) that the SPA opens after warning "After linking you will sign in only through OIDC; your password will be removed." The state is bound to this web session, so the callback adds the identity only to the account that started the link. A successful link removes the password: the account then signs in only through OIDC, keeps its TOTP enrolment, and oidc.sync_role applies to it. There is no unlinking by the user; an Admin can convert the account back to local (convertUserToLocal). Web session only: a token gets 403 (session_required). 409 with oidc_not_enabled while OIDC is off, or oidc_already_linked when the account already signs in through OIDC.
{- "expires_at": "2019-08-24T14:15:22Z"
}Redirect target of the identity provider for a link started by startOidcLink; register MUSTER_PUBLIC_URL/api/v1/me/oidc-identity/callback at the identity provider next to the sign-in callback. Every outcome is a 302 to the profile page. On success the identity (issuer and subject) is added to the account of the web session that started the link and the password is removed; an offline token granted by the link flow is kept on the user, as at sign-in; this session continues as an OIDC session, the user's other sessions end, and the Audit log records it; the redirect goes to /profile. A failure redirects to /profile?error=<code>, with one of identity_linked_elsewhere (the identity belongs to another user; the Audit log records the refusal), no_access (the identity's groups map to no Role and there is no Role for unmatched users, so the account could not sign in through OIDC; the redirect is /profile?error=no_access and the Audit log records the refusal with the groups), oidc_disabled, invalid_request (bad or missing state, code or nonce, no web session, or a state started by another session) and idp_error.
| code | string Authorization code. |
| state | string State issued by |
| error | string Error reported by the identity provider. |
{- "title": "Rate limited",
- "status": 429,
- "detail": "Too many requests for this token.",
- "instance": "/api/v1/alert-groups",
- "retry_after_seconds": 12
}Sessions of the user, the current one marked.
{- "items": [
- {
- "method": "local",
- "id": "AGK7M3QX9P2RTA",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "address": "string",
- "user_agent": "string",
- "current": true
}
]
}Ends every session of the user, the current one included. Web session only.
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Whether TOTP is enrolled, a first code is awaited, and how many recovery codes remain. Service account tokens get 403 (service_account_not_allowed).
{- "enrolled": true,
- "enrolled_at": "2019-08-24T14:15:22Z",
- "enrolment_pending": true,
- "recovery_codes_remaining": 0
}Returns the seed and the otpauth URI once. Enrolment completes when confirmTotpEnrolment receives a first code. Allowed in the session state totp_enrolment_required. 409 (totp_already_enrolled) when TOTP is already on. Web session only.
{- "secret": "string",
- "otpauth_uri": "string"
}Needs proof that the person is at the keyboard: the current password (local users) or a current TOTP or recovery code. Under a TOTP policy that covers the user, the next sign-in demands enrolment again. A wrong proof is 401 (invalid_credentials). Web session only.
| password | string <password> The current password; local users only. |
| totp_code | string Current TOTP code. |
| recovery_code | string A single-use recovery code. |
{- "password": "pa$$word",
- "totp_code": "string",
- "recovery_code": "string"
}{- "title": "Validation failed",
- "status": 400,
- "detail": "The request body is not valid.",
- "instance": "/api/v1/routes",
- "errors": [
- {
- "pointer": "/matchers/0/op",
- "code": "invalid_format",
- "detail": "op must be one of =, !=, =~, !~"
}
]
}Confirms with a first code and issues auth.totp_recovery_codes single-use recovery codes, shown once. Allowed in the session state totp_enrolment_required. 409 (totp_enrolment_not_started) without a begun enrolment, totp_already_enrolled if already confirmed. Web session only.
| code required | string Current TOTP code. |
{- "code": "string"
}{- "codes": [
- "string"
]
}Invalidates the previous codes. Requires a current TOTP code. Web session only.
| code required | string Current TOTP code. |
{- "code": "string"
}{- "codes": [
- "string"
]
}| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| q | string Case-insensitive match on name, login and email. |
| role | string (RoleName) Enum: "admin" "responder" "viewer" Filter by Role. |
| status | string (UserStatus) Enum: "active" "disabled" "deleted" Filter by status. |
| source | string (UserSource) Enum: "local" "oidc" "bootstrap" Filter by source. |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}Returns a single-use password setup link; Muster sends no email. A token may only assign a Role whose Permissions it holds itself (422 permission_not_held at /role).
| name required | string non-empty |
| login required | string non-empty Stored as entered and unique case-insensitively in the Organization ( |
string or null | |
| role required | string (RoleName) Enum: "admin" "responder" "viewer" |
{- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin"
}{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
},
}| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Changes name, email and Role. A Role change ends the user's sessions. Refused with 409 (role_locked) for a Role change of an account that signs in through OIDC while OIDC and oidc.sync_role are both on, and with 409 (last_admin) when it would give the last active Admin a lower Role. A token may only assign a Role whose Permissions it holds itself (422 permission_not_held at /role).
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty |
string or null | |
| role required | string (RoleName) Enum: "admin" "responder" "viewer" |
{- "name": "string",
- "email": "string",
- "role": "admin"
}{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Deactivates and pseudonymizes: the name becomes deleted-user-<id>, the email is erased, sessions end, tokens are revoked and Account links are removed. Every acknowledged Alert Group the user owns becomes firing without an Owner, with an unacknowledged Timeline entry by the system and the reason owner_deleted. Audit log rows are never changed. The last active Admin cannot be deleted (409 last_admin).
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Ends the user's sessions; tokens stop working until the user is enabled again. Every acknowledged Alert Group the user owns becomes firing without an Owner, with an unacknowledged Timeline entry by the system and the reason owner_disabled; enabling the user again gives no acknowledgement back. The last active Admin cannot be disabled (409 last_admin).
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Audited. The user enrols again at the next sign-in if the policy requires it.
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Removes the OIDC identity of an account that signs in through OIDC — created through OIDC or linked — and ends its sessions; the response carries a password setup link, as at user creation, and the Audit log records the conversion. The account keeps its TOTP enrolment and, once the password is set, signs in only with it. 409 with oidc_not_linked when the account does not sign in through OIDC.
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "email": "string",
- "role": "admin",
- "role_locked": true,
- "source": "local",
- "oidc_offline_access": true,
- "sign_in_method": "local",
- "status": "active",
- "totp_enabled": true,
- "time_zone": "string",
- "language": "en",
- "last_sign_in_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
},
}Valid for auth.password_setup_link_ttl, single use. Only for an account that signs in with a password (409 local_user_only for an OIDC account; convert it with convertUserToLocal).
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "expires_at": "2019-08-24T14:15:22Z"
}Name, login and whether the user is deactivated, for the Owner filter, Mention settings and other pickers. Includes deleted users, because their acknowledgements stay visible. Available to everyone who reads Alert Groups, unlike listUsers.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| q | string Case-insensitive match on name and login. |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}
], - "next_cursor": "string"
}The client secret is never returned; client_secret_status shows whether it is set and when it changed.
{- "enabled": true,
- "display_name": "string",
- "client_id": "string",
- "client_secret_expires_on": "2019-08-24",
- "scopes": [
- "string"
], - "groups_claim": "string",
- "group_mappings": [
- {
- "group": "string",
- "role": "admin"
}
], - "unmatched_role": "none",
- "sync_role": true,
- "skip_totp_with_idp_mfa": true,
- "client_secret_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "warnings": [
- {
- "kind": "nobody_can_sign_in",
- "expires_on": "2019-08-24",
- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "role": "admin"
}
], - "updated_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields; omitted optional fields keep their value. Saving with an empty mapping and no Role for unmatched users returns the warning nobody_can_sign_in in the result. The Audit log diff shows only that the client secret changed.
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| enabled required | boolean |
| display_name | string Provider name for the button "Sign in with {display_name}". Defaults to the host of the issuer URL; a read leaves it out while the default applies, and an empty value returns to the default. |
| issuer_url required | string <uri> |
| client_id required | string |
| client_secret_expires_on | string or null <date> Optional expiry date of the client secret; the OIDC settings warn within |
| scopes | Array of strings Scopes requested at sign-in and linking. Muster always adds |
| groups_claim required | string |
required | Array of objects (OidcGroupMapping) |
| unmatched_role required | string (OidcUnmatchedRole) Enum: "none" "viewer" "responder" Role for users without a matching group; |
| sync_role required | boolean On: the identity provider decides the Role at every sign-in. Off: the mapping applies only when the user is created. |
| skip_totp_with_idp_mfa required | boolean |
| client_secret | string <password> Write-only Secret. Omit to keep the stored one. |
required | object (ProxyConfigInput) Per-client proxy as written. Omitting |
{- "enabled": true,
- "display_name": "string",
- "client_id": "string",
- "client_secret_expires_on": "2019-08-24",
- "scopes": [
- "string"
], - "groups_claim": "string",
- "group_mappings": [
- {
- "group": "string",
- "role": "admin"
}
], - "unmatched_role": "none",
- "sync_role": true,
- "skip_totp_with_idp_mfa": true,
- "client_secret": "pa$$word",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password": "string"
}
}{- "enabled": true,
- "display_name": "string",
- "client_id": "string",
- "client_secret_expires_on": "2019-08-24",
- "scopes": [
- "string"
], - "groups_claim": "string",
- "group_mappings": [
- {
- "group": "string",
- "role": "admin"
}
], - "unmatched_role": "none",
- "sync_role": true,
- "skip_totp_with_idp_mfa": true,
- "client_secret_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "warnings": [
- {
- "kind": "nobody_can_sign_in",
- "expires_on": "2019-08-24",
- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "role": "admin"
}
], - "updated_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Fetches discovery through the outbound HTTP package, with the saved proxy, and reports whether the groups claim is advertised (warning groups_claim_missing).
{- "ok": true,
- "via": "direct",
- "latency_ms": 0,
- "issuer": "string",
- "authorization_endpoint": "string",
- "token_endpoint": "string",
- "jwks_uri": "string",
- "error": "string",
- "warnings": [
- {
- "kind": "nobody_can_sign_in",
- "expires_on": "2019-08-24",
- "user": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "role": "admin"
}
]
}Newest first. The log is append-only; configuration changes carry a before/after diff in which Secrets only show that they changed.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| from | string <date-time> Start of the time range (RFC 3339, UTC). |
| to | string <date-time> End of the time range (RFC 3339, UTC). |
| actor | string Actor |
| action | string Action type, for example |
| resource_type | string Resource type, for example |
| resource_id | string Resource |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "at": "2019-08-24T14:15:22Z",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "token_id": "AGK7M3QX9P2RTA",
- "token_name": "string",
- "transport": "ui",
- "action": "string",
- "resource_type": "string",
- "resource_id": "string",
- "resource_name": "string",
- "diff": [
- {
- "pointer": "string",
- "before": null,
- "after": null,
- "secret_changed": true
}
], - "details": { }
}
], - "next_cursor": "string"
}Values are never returned. Each token shows when and from which address it was last used. Service account tokens get 403 (service_account_not_allowed).
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "last_used_address": "string",
- "permissions": [
- "alert-groups:read"
]
}
]
}Shows the token once. Its Permissions must be a subset of the Permissions the caller holds now (422 permission_not_held on /permissions/<i>). Web session only: a token can never mint another token.
| name required | string non-empty |
| permissions required | Array of strings (Permission) non-empty Items Enum: "alert-groups:read" "alert-groups:acknowledge" "alert-groups:resolve" "alert-groups:snooze" "alert-groups:note" "alerts:read" "integrations:read" "integrations:write" "stored-snapshots:read" "routes:read" "routes:write" "connections:read" "connections:write" "destinations:read" "destinations:write" "destinations:test" "link-rules:read" "link-rules:write" "lookup-tables:read" "lookup-tables:write" "templates:preview" "users:read" "users:write" "oidc:read" "oidc:write" "service-accounts:read" "service-accounts:write" "organization:write" "organization:read" "audit-log:read" "system-status:read" Must be a subset of the Permissions the caller holds. |
| expires_at | string or null <date-time> |
{- "name": "string",
- "permissions": [
- "alert-groups:read"
], - "expires_at": "2019-08-24T14:15:22Z"
}{- "token": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "last_used_address": "string",
- "permissions": [
- "alert-groups:read"
]
}, - "value": "string"
}Revokes the token at once. Web session only.
| token_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Token id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}A token may only assign a Role whose Permissions it holds itself (422 permission_not_held at /role).
| name required | string non-empty |
| role required | string (RoleName) Enum: "admin" "responder" "viewer" |
{- "name": "string",
- "role": "admin"
}{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}A token may only assign a Role whose Permissions it holds itself (422 permission_not_held at /role).
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty |
| role required | string (RoleName) Enum: "admin" "responder" "viewer" |
{- "name": "string",
- "role": "admin"
}{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Revokes its tokens.
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Its tokens stop working until the account is enabled again.
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Makes a disabled Service account usable again; its tokens work again.
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
{- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "role": "admin",
- "status": "active",
- "token_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "last_used_address": "string"
}
]
}Shows the token once. Web session only: a token can never mint another token.
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
| name required | string non-empty |
| expires_at | string or null <date-time> |
{- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z"
}{- "token": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "expires_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z",
- "last_used_address": "string"
}, - "value": "string"
}Revokes the token at once. Web session only: a token can never revoke a token.
| service_account_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Service account |
| token_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Token id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Organization settings, the outbound address policy, the Keyring status and severity values seen.
Readable by every signed-in identity (the basic read of the Organization needs no Permission). Secrets (the outgoing heartbeat URL, proxy passwords) show only set and updated_at.
{- "name": "string",
- "time_zone": "string",
- "workday_start": "09:00",
- "week_start": "monday",
- "severity_label": "string",
- "severity_mapping": [
- {
- "value": "string",
- "level": "critical"
}
], - "severity_styles": [
- {
- "level": "critical",
- "emoji": "string",
- "color": "string"
}
], - "critical_is_urgent": true,
- "instance_labels": [
- "string"
], - "retention": {
- "stored_snapshots_days": 1,
- "alert_details_days": 1,
- "alert_group_summaries_days": 1,
- "audit_log_days": 1
}, - "totp_required": "nobody",
- "oidc_token_grace_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "outgoing_heartbeat": {
- "url_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}
}, - "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one. An omitted Secret field keeps the stored Secret. null on outgoing_heartbeat.url or a proxy password clears it. Every field is validated; an invalid one gets 422 at the full JSON pointer of the field, such as /severity_styles/1/color or /retention/alert_details_days, with invalid_format, duplicate, required, too_short, too_long, out_of_range or retention_order. A retention period or oidc_token_grace_seconds beyond its maximum, a workday_start that is not HH:MM on the 24-hour clock and a week_start that is not a day of the week are refused with 400 by request validation, invalid_format at /workday_start or /week_start; out_of_range and invalid_format are the second, defensive check of the same rules. A change is recorded in the Audit log as organization.updated with its before/after diff and announced with the organization hint; Severity levels and Instance labels apply to later evaluations only.
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty |
| time_zone required | string IANA time zone used for times in messages. |
| workday_start | string^([01][0-9]|2[0-3]):[0-5][0-9]$ The start of the working day, |
| week_start | string (Weekday) Enum: "monday" "tuesday" "wednesday" "thursday" "friday" "saturday" "sunday" A day of the week. As the Organization's |
| severity_label required | string Label that carries severity. |
required | Array of objects (SeverityMappingEntry) Values of the severity label mapped to Severity levels. Unmapped values count as warning. |
required | Array of objects (SeverityLevelStyle) |
| critical_is_urgent required | boolean |
| instance_labels required | Array of strings |
required | object (RetentionSettings) Retention periods in days, from 1 to 36500 (100 years). |
| totp_required required | string (TotpPolicy) Enum: "nobody" "local_users" "everyone" Who must enrol TOTP. |
| oidc_token_grace_seconds required | integer [ 1 .. 3153600000 ]
|
required | object |
{- "name": "string",
- "time_zone": "string",
- "workday_start": "09:00",
- "week_start": "monday",
- "severity_label": "string",
- "severity_mapping": [
- {
- "value": "string",
- "level": "critical"
}
], - "severity_styles": [
- {
- "level": "critical",
- "emoji": "string",
- "color": "string"
}
], - "critical_is_urgent": true,
- "instance_labels": [
- "string"
], - "retention": {
- "stored_snapshots_days": 1,
- "alert_details_days": 1,
- "alert_group_summaries_days": 1,
- "audit_log_days": 1
}, - "totp_required": "nobody",
- "oidc_token_grace_seconds": 1,
- "outgoing_heartbeat": {
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password": "string"
}
}
}{- "name": "string",
- "time_zone": "string",
- "workday_start": "09:00",
- "week_start": "monday",
- "severity_label": "string",
- "severity_mapping": [
- {
- "value": "string",
- "level": "critical"
}
], - "severity_styles": [
- {
- "level": "critical",
- "emoji": "string",
- "color": "string"
}
], - "critical_is_urgent": true,
- "instance_labels": [
- "string"
], - "retention": {
- "stored_snapshots_days": 1,
- "alert_details_days": 1,
- "alert_group_summaries_days": 1,
- "audit_log_days": 1
}, - "totp_required": "nobody",
- "oidc_token_grace_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "outgoing_heartbeat": {
- "url_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}
}, - "etag": "string"
}The outbound address policy with the rules that always apply. Needs organization:read.
{- "policy": "standard",
- "allowed": [
- "string"
], - "denied": [
- "string"
], - "always_blocked": [
- "string"
], - "etag": "string"
}Replaces the policy and its lists. Requires If-Match; a stale ETag gets 412. Each entry is a network in CIDR form or a bare address, a host name, or a domain written *.example.org; an entry that does not parse gets 422 with invalid_format and a repeated one duplicate, at /allowed/<i> or /denied/<i>. always_blocked is read-only and ignored. The change takes effect at once on every replica, idle pooled connections included, is recorded in the Audit log as outbound_policy.updated and is announced with the organization hint. Needs organization:write.
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| policy required | string Enum: "standard" "strict" |
| allowed required | Array of strings Allowed networks (CIDR), host names and domains. |
| denied required | Array of strings Denied networks, host names and domains. A denied entry always wins. |
{- "policy": "standard",
- "allowed": [
- "string"
], - "denied": [
- "string"
]
}{- "policy": "standard",
- "allowed": [
- "string"
], - "denied": [
- "string"
], - "always_blocked": [
- "string"
], - "etag": "string"
}Every key id in the environment, which is active, which live replicas hold which, and whether anything still depends on an older key. Activation is the CLI command muster secrets rotate-key --activate <id> --actor <name>.
{- "keys": [
- {
- "id": "string",
- "active": true,
- "held_by": [
- "string"
], - "missing_on": [
- "string"
], - "needed": true,
- "removable": true,
- "state": "active"
}
]
}Values of the severity label seen in the last organization.severity_values_window, with counts, the most frequent first and at most 500 values; unmapped values count as warning.
{- "items": [
- {
- "value": "string",
- "count": 0,
- "level": "critical",
- "mapped": true
}
], - "window_days": 0
}Integrations, their tokens, learned Alertmanager routes, the Alerts view and Stored Snapshots.
Includes the built-in "Muster" Integration, marked builtin.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 0,
- "state": "not_configured",
- "last_signal_at": "2019-08-24T14:15:22Z",
- "lost_since": "2019-08-24T14:15:22Z"
}, - "last_snapshot_at": "2019-08-24T14:15:22Z",
- "snapshot_count": 0,
- "warnings": [
- {
- "kind": "snapshot_truncated",
- "truncated_group_count": 0,
- "route_path": "string",
- "repeat_interval_seconds": 0,
- "since": "2019-08-24T14:15:22Z"
}
], - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}| name required | string non-empty Unique in the Organization. |
| description | string |
| connection_mode required | string Value: "webhook_only" The Connection mode; in L1 the only mode is |
required | object (Labels) Label names and values. |
| duplicate_window_seconds required | integer >= 1 |
required | object (HeartbeatSettingsInput) |
{- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 1
}
}{- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 0,
- "state": "not_configured",
- "last_signal_at": "2019-08-24T14:15:22Z",
- "lost_since": "2019-08-24T14:15:22Z"
}, - "last_snapshot_at": "2019-08-24T14:15:22Z",
- "snapshot_count": 0,
- "warnings": [
- {
- "kind": "snapshot_truncated",
- "truncated_group_count": 0,
- "route_path": "string",
- "repeat_interval_seconds": 0,
- "since": "2019-08-24T14:15:22Z"
}
], - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
{- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 0,
- "state": "not_configured",
- "last_signal_at": "2019-08-24T14:15:22Z",
- "lost_since": "2019-08-24T14:15:22Z"
}, - "last_snapshot_at": "2019-08-24T14:15:22Z",
- "snapshot_count": 0,
- "warnings": [
- {
- "kind": "snapshot_truncated",
- "truncated_group_count": 0,
- "route_path": "string",
- "repeat_interval_seconds": 0,
- "since": "2019-08-24T14:15:22Z"
}
], - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one.
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty Unique in the Organization. |
| description | string |
| connection_mode required | string Value: "webhook_only" The Connection mode; in L1 the only mode is |
required | object (Labels) Label names and values. |
| duplicate_window_seconds required | integer >= 1 |
required | object (HeartbeatSettingsInput) |
{- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 1
}
}{- "name": "string",
- "description": "string",
- "connection_mode": "webhook_only",
- "static_labels": {
- "property1": "string",
- "property2": "string"
}, - "duplicate_window_seconds": 1,
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "heartbeat": {
- "enabled": true,
- "timeout_seconds": 0,
- "state": "not_configured",
- "last_signal_at": "2019-08-24T14:15:22Z",
- "lost_since": "2019-08-24T14:15:22Z"
}, - "last_snapshot_at": "2019-08-24T14:15:22Z",
- "snapshot_count": 0,
- "warnings": [
- {
- "kind": "snapshot_truncated",
- "truncated_group_count": 0,
- "route_path": "string",
- "repeat_interval_seconds": 0,
- "since": "2019-08-24T14:15:22Z"
}
], - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Soft delete: its tokens stop working at once, its open Alerts are resolved with the reason "Integration {name} deleted", its Internal alerts are resolved, and its open Alert Groups are resolved. The built-in Integration cannot be deleted (409, builtin_immutable).
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Values are never returned.
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}
]
}The token allows ingestion and Heartbeat and nothing else. The value and the ready Alertmanager snippet that contains it are returned once; a new snippet means a new token.
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
| name | string Optional label to tell tokens apart during rotation. |
{- "name": "string"
}{- "token": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "created_at": "2019-08-24T14:15:22Z",
- "last_used_at": "2019-08-24T14:15:22Z"
}, - "value": "string",
- "alertmanager_snippet": "string",
- "heartbeat_snippet": "string"
}| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
| integration_token_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration token id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Routes taken from the groupKey of Snapshots, with the learned repeat interval and the resulting time to resolve by absence.
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
{- "items": [
- {
- "route_path": "string",
- "learned_repeat_interval_seconds": 0,
- "resolve_by_absence_after_seconds": 0,
- "truncated_group_count": 0,
- "long_interval_warning": true,
- "recommended_snippet": "string"
}
]
}The Alerts Muster currently tracks for the Integration. Resolved Alerts stay for retention.alert_details. Label filters follow the scheme of label on listAlertGroups.
| integration_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Integration |
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| state | string (AlertState) Enum: "firing" "resolved" Filter by state. |
| label | Array of strings Examples:
Label filter: one Alertmanager-syntax Matcher per repeat of the parameter, combined with AND. Each value is a whole matcher: |
| q | string Case-insensitive match on label values. |
| sort | string Default: "-last_seen_at" Enum: "last_seen_at" "-last_seen_at" "starts_at" "-starts_at" Sort field; a leading |
{- "items": [
- {
- "fingerprint": "string",
- "labels": {
- "property1": "string",
- "property2": "string"
}, - "annotations": {
- "property1": "string",
- "property2": "string"
}, - "state": "firing",
- "resolve_reason": "resolved",
- "resolve_reason_text": "string",
- "starts_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_seen_at": "2019-08-24T14:15:22Z",
- "alertmanager_groups": [
- "string"
], - "static_label_warnings": [
- "string"
], - "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "severity_level": "critical",
- "severity_raw": "string",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "next_cursor": "string"
}Kept for retention.stored_snapshots. Replay is the CLI command muster ingest replay.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| integration required | string Integration |
| from | string <date-time> Start of the time range (RFC 3339, UTC). |
| to | string <date-time> End of the time range (RFC 3339, UTC). |
| state | Array of strings (SnapshotState) Items Enum: "pending" "processed" "failed" Only Snapshots in these processing states. |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "integration": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "received_at": "2019-08-24T14:15:22Z",
- "processed_at": "2019-08-24T14:15:22Z",
- "size_bytes": 0,
- "group_key": "string",
- "alert_count": 0,
- "truncated_alerts": 0,
- "state": "pending",
- "processing_error": "string"
}
], - "next_cursor": "string"
}| stored_snapshot_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Stored Snapshot id. |
{- "id": "AGK7M3QX9P2RTA",
- "integration": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "received_at": "2019-08-24T14:15:22Z",
- "processed_at": "2019-08-24T14:15:22Z",
- "size_bytes": 0,
- "group_key": "string",
- "alert_count": 0,
- "truncated_alerts": 0,
- "state": "pending",
- "processing_error": "string",
- "body": "string",
- "content_type": "string",
- "body_encoding": "utf8"
}Checks the token, then the body size, stores the body as a Stored Snapshot exactly as received and answers 202 after the write commits, without waiting for processing. It never answers 400: a body that is not JSON, or does not look like an Alertmanager payload, is stored and fails later as a processing error (log event, muster_ingest_failed_snapshots_total, Stored Snapshot state failed), because Alertmanager does not retry a 4xx and the notification would be lost. Not rate-limited. Counted in muster_ingest_requests_total with the outcome accepted, unauthorized or too_large. The only 5xx is a failed write, which Alertmanager retries. Ingestion is excluded from request validation by the spec: the handler reads the raw body and the generated types are not used for it.
Any bytes up to ingest.body_limit. Alertmanager sends application/json, and the webhook contact point of Grafana Alerting sends the same JSON; see AlertmanagerWebhook.
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}For senders that cannot set a header. Identical to ingestSnapshot. Logs record the route pattern, never the path.
| ingest_token required | string An Integration token. Never logged. |
Any bytes up to ingest.body_limit. Alertmanager sends application/json, and the webhook contact point of Grafana Alerting sends the same JSON; see AlertmanagerWebhook.
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Any request carrying one of the Integration's tokens counts as a signal; the body is ignored. The first signal moves the Heartbeat from waiting to live. While the Integration's Heartbeat is off, the request is answered 204 and nothing is recorded.
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Any request carrying one of the Integration's tokens counts as a signal; the body is ignored. The first signal moves the Heartbeat from waiting to live. While the Integration's Heartbeat is off, the request is answered 204 and nothing is recorded.
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| ingest_token required | string An Integration token. Never logged. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| ingest_token required | string An Integration token. Never logged. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Mattermost button presses and the optional Telegram webhook, on the ingest listener.
Sent by the Mattermost server. Mattermost does not sign the request: Muster verifies the signed action id with the key it names, checks that post_id and channel_id belong to the post the id was issued for, maps user_id to a User through the Account link of this Connection and dispatches the Command with the Transport mattermost. Every request is answered with 200 and a JSON object, an unknown or deleted Connection, a bad signature and a body that is not JSON or does not match MattermostActionRequest included; request validation does not answer 400 here. Whatever the person who pressed must read — a refusal, a failure, "not linked", or "not verified" for a press on a post Muster delivered in that channel — goes first as a separate ephemeral post, shown in the channel view, and the answer is then an empty object. That post needs the create_post_ephemeral permission, which a bot with the role Member lacks; when it is refused, or fails in any other way, the answer carries the text as ephemeral_text, which Mattermost shows to that person alone in the Thread of the Root message and which needs no permission. Every other answer is an empty object, so the endpoint tells a caller nothing about which Connection ids exist. The answer never carries update: only the delivery worker edits the Root message.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| user_id required | string |
| user_name | string |
| channel_id required | string |
| team_id | string |
| post_id required | string |
| trigger_id | string |
| type | string |
| data_source | string |
required | object (MattermostActionContext) The integration data Muster put on the button. Mattermost does not sign the request, so authenticity rests on the signed action id. |
| property name* additional property | any |
{- "user_id": "string",
- "user_name": "string",
- "channel_id": "string",
- "team_id": "string",
- "post_id": "string",
- "trigger_id": "string",
- "type": "string",
- "data_source": "string",
- "context": {
- "action": "string",
- "key_id": "string"
}
}{- "ephemeral_text": "string",
- "skip_slack_parsing": true
}Used only when the Connection's update mode is webhook. A request without the right secret token header, or for a Connection that does not exist or is not in webhook mode, is answered 401 and changes nothing.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| update_id required | integer <int64> |
| property name* additional property | any |
{- "update_id": 0
}{- "title": "Validation failed",
- "status": 400,
- "detail": "The request body is not valid.",
- "instance": "/api/v1/routes",
- "errors": [
- {
- "pointer": "/matchers/0/op",
- "code": "invalid_format",
- "detail": "op must be one of =, !=, =~, !~"
}
]
}Used only when the Bridge Connection's event delivery mode is push: the bridge posts each event, one per request, signed as Standard Webhooks specifies with the Connection's push secret. Muster verifies webhook-signature — v1, followed by the base64 of HMAC-SHA256 over <webhook-id>.<webhook-timestamp>.<body> with the decoded secret, any of several signatures separated by spaces — in constant time, refuses a webhook-timestamp further than bridge.push_tolerance from its real clock, and requires webhook-id to equal the event's id. It handles each event id of a Connection once within bridge.event_dedup_window, answers the person behind the event, when it does, before it answers 204, and answers 204 also for an id it handled before. A bad signature, a timestamp out of range, an unknown or deleted Connection and a Connection in poll mode are all answered 401 and change nothing, so the endpoint reveals nothing about which Connections exist; a body that is no event of the Bridge protocol, or whose id is not webhook-id, is answered 400, and the bridge drops it; an event whose handling failed is answered 500, is not recorded as handled, and the bridge sends it again. Request validation does not answer 400 here: the handler decides every answer.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| webhook-id required | string^[!-~]{1,200}$ The event's |
| webhook-timestamp required | string^[0-9]{1,12}$ Unix time of this attempt, in seconds. |
| webhook-signature required | string >= 4 characters
|
| id required | string^[!-~]{1,200}$ Stable across retries and polls; Muster handles each id of a Connection once. Printable ASCII without spaces, so that it can travel as the |
| type required | string Value: "press" |
| occurred_at required | string <date-time> When it happened in the messenger, or when the bridge learned of it. |
| message_id required | string The message the button belongs to, a Root message or a Thread reply. |
required | object (BridgePerson) A messenger account as a bridge names it, a copy of the schema |
| data required | string The button's |
{- "id": "string",
- "type": "press",
- "occurred_at": "2019-08-24T14:15:22Z",
- "message_id": "string",
- "user": {
- "external_id": "string",
- "display_name": "string",
- "handle": "string"
}, - "data": "string"
}{- "title": "Validation failed",
- "status": 400,
- "detail": "The request body is not valid.",
- "instance": "/api/v1/routes",
- "errors": [
- {
- "pointer": "/matchers/0/op",
- "code": "invalid_format",
- "detail": "op must be one of =, !=, =~, !~"
}
]
}The first Route whose Matchers all match takes an Alert. The Default route is always last. The ETag covers the order and is what reorderRoutes expects in If-Match.
{- "items": [
- {
- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
]
}Inserted before the Default route. Fields omitted from policy are not defaulted: fetch a profile with listRouteProfiles to pre-fill the form. Templates are parsed and dry-run against recent Stored Snapshots; a template that fails is refused with 422 and the error position.
| name required | string non-empty Unique in the Organization. |
| description | string |
required | Array of objects (Matcher) Combined with AND. The Default route has none. |
| urgent required | boolean |
| group_key required | Array of strings Label names whose values split the Route's Alerts into Alert Groups. A missing label counts as an empty value. |
| destination_ids required | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] |
required | object (RoutePolicy) |
{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}
}{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| route_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Route |
{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one.
| route_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Route |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty Unique in the Organization. |
| description | string |
required | Array of objects (Matcher) Combined with AND. The Default route has none. |
| urgent required | boolean |
| group_key required | Array of strings Label names whose values split the Route's Alerts into Alert Groups. A missing label counts as an empty value. |
| destination_ids required | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] |
required | object (RoutePolicy) |
{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}
}{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Refused with 409 default-route-immutable for the Default route and with 409 route-has-open-alert-groups (carrying open_alert_group_count) while open Alert Groups remain; move them first with moveOpenAlertGroups.
| route_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Route |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Replaces the order of all Routes except the Default route, which cannot be moved. If-Match carries the ETag of listRoutes; a stale one gets 412. A list that contains the Default route is 409 (default-route-immutable); a set of ids that differs from the current set is 422 (route_set_mismatch).
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| route_ids required | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] Every Route except the Default route, in the new order. |
{- "route_ids": [
- "AGK7M3QX9P2RTA"
]
}{- "items": [
- {
- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
]
}Adds a moved_to_default_route Timeline entry to each moved Alert Group. Afterwards the Route can be deleted. A moved Alert Group keeps its Group key values but takes no new Alerts and never reopens; it stays open until its Alerts resolve or a person resolves it.
| route_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Route |
{- "moved": 0
}The two starting sets of Route settings, On-call and Informational, read from the built-in defaults. They only pre-fill the create form; they cannot be edited or stored.
{- "items": [
- {
- "id": "on_call",
- "name": "string",
- "urgent": true,
- "group_key": [
- "string"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}
}
]
}Counts the Alert Groups that the Stored Snapshots of the period would have produced with the current and with the proposed Group key.
| route_id | string or null (NullablePublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... A saved Route; its current Group key is the "current" side. |
| proposed_group_key required | Array of strings |
| period_seconds | integer >= 1 Defaults to |
Array of objects (Matcher) Matchers to preview instead of, or without, a saved Route's own. |
{- "route_id": "AGK7M3QX9P2RTA",
- "proposed_group_key": [
- "string"
], - "period_seconds": 1,
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
]
}{- "period_seconds": 0,
- "truncated": true,
- "current": {
- "alert_group_count": 0,
- "examples": [
- {
- "group_key_values": {
- "property1": "string",
- "property2": "string"
}, - "alert_count": 0
}
]
}, - "proposed": {
- "alert_group_count": 0,
- "examples": [
- {
- "group_key_values": {
- "property1": "string",
- "property2": "string"
}, - "alert_count": 0
}
]
}
}A Route for MusterHeartbeatLost when an Integration has a Heartbeat and no Route other than the Default route matches it; from the first Destination on, a Route for alertname=~"Muster.*". Dismissals are remembered per user.
{- "items": [
- {
- "id": "heartbeat_lost",
- "route": {
- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}
}
}
]
}Creates the suggested Route at the top of the list; the Route for internal_alerts goes directly below the last Route other than the Default route that already takes an Internal alert, such as the Route for MusterHeartbeatLost, and at the top when none does. 409 (suggestion_obsolete) when it no longer applies: a matching Route exists now, it was accepted already, or no Destination exists for internal_alerts; 422 (required at /destination_ids) when internal_alerts is accepted without Destinations.
| suggestion_id required | string (RouteSuggestionId) Enum: "heartbeat_lost" "internal_alerts" Route suggestion id. |
| destination_ids | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] Destinations for the created Route; required for |
{- "destination_ids": [
- "AGK7M3QX9P2RTA"
]
}{- "name": "string",
- "description": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "urgent": true,
- "group_key": [
- "string"
], - "destination_ids": [
- "AGK7M3QX9P2RTA"
], - "policy": {
- "reopen_window_seconds": 0,
- "grace_period_seconds": 0,
- "urgent_rise_removes_ack": true,
- "snooze_durations_seconds": [
- 1
], - "thread_batching_window_seconds": 0,
- "storm_threshold": 1,
- "language": "en",
- "templates": {
- "root_message": "string",
- "line": "string",
- "ack_timeout_notice": "string"
}, - "ack_timeout": {
- "enabled": true,
- "first_interval_seconds": 1
}, - "reminders": {
- "enabled": true,
- "first_interval_seconds": 1,
- "cap_seconds": 1
}, - "auto_unacknowledge": true
}, - "id": "AGK7M3QX9P2RTA",
- "position": 0,
- "is_default": true,
- "destinations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "storm_active": true,
- "storm": {
- "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}, - "open_alert_group_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Remembered for the calling user only, so Service account tokens get 403 (service_account_not_allowed). 409 (suggestion_obsolete) when it no longer applies.
| suggestion_id required | string (RouteSuggestionId) Enum: "heartbeat_lost" "internal_alerts" Route suggestion id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}The main working list. Without status it returns open Alert Groups (firing, acknowledged, snoozed). Without from and to it covers the last alert_group.list_range (7 days) and selects Alert Groups whose lifetime overlaps the range, so one that has been firing for weeks is always included. Search matches #N and text in the title or summary. Changes arrive as alert-group and alert-groups hints.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| status | Array of strings (AlertGroupStatus) Items Enum: "firing" "acknowledged" "snoozed" "resolved" Only these statuses. Default: firing, acknowledged and snoozed. |
| route | Array of strings Only these Routes ( |
| integration | Array of strings Only Alert Groups with Alerts from these Integrations ( |
| severity | Array of strings (SeverityLevel) Items Enum: "critical" "warning" "info" Only these Severity levels. |
| urgent | boolean Only Urgent (true) or non-Urgent (false) Alert Groups. |
| resolved_by | string (ResolverKind) Enum: "user" "system" Only Alert Groups resolved by a person or by the system. |
| resolve_reason | string (ResolveReason) Enum: "resolved" "gone" "stale" "integration_deleted" With |
| reopened | boolean True: Reopen count above zero. |
| label | Array of strings Examples:
Label filter: one Alertmanager-syntax Matcher per repeat of the parameter, combined with AND. Each value is a whole matcher: |
| owner | string A user |
| snoozed_no_end | boolean True: only Alert Groups snoozed with no end. False: every Alert Group but those. |
| delivery_problem | boolean Any Destination is Not delivered, waiting for a Broken Destination, deleted in the messenger or has a Thread not attached. |
| unclaimed | boolean Only Unclaimed Alert Groups. |
| from | string <date-time> Start of the time range (RFC 3339, UTC). |
| to | string <date-time> End of the time range (RFC 3339, UTC). |
| number | integer >= 1 The Alert Group with exactly this |
| q | string Search by text in the title or |
| sort | string Default: "-started_at" Enum: "started_at" "-started_at" "last_changed_at" "-last_changed_at" Sort field; a leading |
| label_columns | Array of strings Label names whose shared value is returned in |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
], - "next_cursor": "string"
}Counts per status tab for the same filters as listAlertGroups, status excluded.
| route | Array of strings Only these Routes ( |
| integration | Array of strings Only Alert Groups with Alerts from these Integrations ( |
| severity | Array of strings (SeverityLevel) Items Enum: "critical" "warning" "info" Only these Severity levels. |
| urgent | boolean Only Urgent (true) or non-Urgent (false) Alert Groups. |
| resolved_by | string (ResolverKind) Enum: "user" "system" Only Alert Groups resolved by a person or by the system. |
| resolve_reason | string (ResolveReason) Enum: "resolved" "gone" "stale" "integration_deleted" With |
| reopened | boolean True: Reopen count above zero. |
| label | Array of strings Examples:
Label filter: one Alertmanager-syntax Matcher per repeat of the parameter, combined with AND. Each value is a whole matcher: |
| owner | string A user |
| snoozed_no_end | boolean True: only Alert Groups snoozed with no end. False: every Alert Group but those. |
| delivery_problem | boolean Any Destination is Not delivered, waiting for a Broken Destination, deleted in the messenger or has a Thread not attached. |
| unclaimed | boolean Only Unclaimed Alert Groups. |
| from | string <date-time> Start of the time range (RFC 3339, UTC). |
| to | string <date-time> End of the time range (RFC 3339, UTC). |
| q | string Search by text in the title or |
{- "firing": 0,
- "acknowledged": 0,
- "snoozed": 0,
- "resolved": 0,
- "all": 0
}Number of Alert Groups, time to acknowledge and time to resolve (median and 95th percentile), as totals and per day of start, from the summary rows, one item per Route or per Integration as group_by says. Narrow it with route or integration ids (the one that matches group_by); without them every Route or Integration is returned. An Alert Group with Alerts from several Integrations counts for each.
| group_by required | string Enum: "route" "integration" What one item stands for. |
| route | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] Example: route=AGK7M3QX9P2RTA Only these Routes ( |
| integration | Array of strings (PublicId) [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] Example: integration=AGK7M3QX9P2RTA Only these Integrations ( |
| from | string <date-time> Start of the time range (RFC 3339, UTC). |
| to | string <date-time> End of the time range (RFC 3339, UTC). |
| time_zone | string IANA time zone that splits days; defaults to the Organization's. |
{- "group_by": "route",
- "from": "2019-08-24T14:15:22Z",
- "to": "2019-08-24T14:15:22Z",
- "items": [
- {
- "subject": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "alert_group_count": 0,
- "time_to_acknowledge": {
- "count": 0,
- "median_seconds": 0,
- "p95_seconds": 0
}, - "time_to_resolve": {
- "count": 0,
- "median_seconds": 0,
- "p95_seconds": 0
}, - "per_day": [
- {
- "date": "2019-08-24",
- "alert_group_count": 0,
- "time_to_acknowledge": {
- "count": 0,
- "median_seconds": 0,
- "p95_seconds": 0
}, - "time_to_resolve": {
- "count": 0,
- "median_seconds": 0,
- "p95_seconds": 0
}
}
]
}
]
}An Alert Group whose details were removed by retention opens as its summary with the notice details_removed; its Notes stay until the summary row is removed.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| state | string (AlertState) Enum: "firing" "resolved" Filter by firing or resolved; firing Alerts come first. |
{- "items": [
- {
- "fingerprint": "string",
- "integration": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "labels": {
- "property1": "string",
- "property2": "string"
}, - "annotations": {
- "property1": "string",
- "property2": "string"
}, - "state": "firing",
- "resolve_reason": "resolved",
- "resolve_reason_text": "string",
- "starts_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_seen_at": "2019-08-24T14:15:22Z",
- "alertmanager_groups": [
- "string"
], - "source_url": "string"
}
], - "next_cursor": "string"
}Entries of all kinds, with delivery events merged in by time as the kind delivery. Lifecycle events carry event, loudness and mentions. Notes are kept as long as the summary row, so after the details were removed by retention the Timeline still returns them.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| kind | Array of strings (TimelineKind) Items Enum: "status" "alerts" "notes" "timers" "delivery" "system" Only these kinds. |
| order | string Default: "desc" Enum: "asc" "desc" Newest first by default. |
{- "items": [
- {
- "id": "TEK7M3QX9P2R01",
- "at": "2026-10-03T09:11:00Z",
- "kind": "status",
- "actor": {
- "kind": "system",
- "reason": "ingestion"
}, - "event": "created",
- "loudness": "loud",
- "mentions": [
- "new_alert_group"
], - "from_status": null,
- "to_status": "firing"
}, - {
- "id": "TEK7M3QX9P2R02",
- "at": "2026-10-03T09:12:00Z",
- "kind": "alerts",
- "actor": {
- "kind": "system",
- "reason": "ingestion"
}, - "event": "alerts_added",
- "loudness": "loud",
- "mentions": [
- "new_alerts"
], - "fingerprints": [
- "3a1f9c0be2d47a55"
]
}, - {
- "id": "TEK7M3QX9P2R03",
- "at": "2026-10-03T09:13:00Z",
- "kind": "status",
- "actor": {
- "kind": "user",
- "id": "SR2K9D1VW3MPTE",
- "name": "Alice Smith",
- "transport": "mattermost"
}, - "event": "acknowledged",
- "loudness": "quiet",
- "mentions": [ ],
- "from_status": "firing",
- "to_status": "acknowledged",
- "owner": {
- "id": "SR2K9D1VW3MPTE",
- "name": "Alice Smith",
- "login": "alice",
- "deactivated": false
}
}, - {
- "id": "NEK7M3QX9P2R04",
- "at": "2026-10-03T09:14:00Z",
- "kind": "notes",
- "actor": {
- "kind": "user",
- "id": "SR2K9D1VW3MPTE",
- "name": "Alice Smith",
- "transport": "mattermost"
}, - "event": "note_added",
- "loudness": "quiet",
- "mentions": [ ],
- "note": {
- "id": "NEK7M3QX9P2R04",
- "body": "Rolling back the deploy.",
- "author": {
- "kind": "user",
- "id": "SR2K9D1VW3MPTE",
- "name": "Alice Smith",
- "login": "alice",
- "deactivated": false
}, - "transport": "ui",
- "created_at": "2026-10-03T09:14:00Z"
}
}, - {
- "id": "TEK7M3QX9P2R05",
- "at": "2026-10-03T09:15:00Z",
- "kind": "timers",
- "actor": {
- "kind": "system",
- "reason": "ingestion"
}, - "event": "reminder",
- "loudness": "loud",
- "mentions": [
- "owner"
], - "notice_number": 1
}, - {
- "id": "DEK7M3QX9P2R06",
- "at": "2026-10-03T09:16:00Z",
- "kind": "delivery",
- "actor": {
- "kind": "system",
- "reason": "ingestion"
}, - "delivery_event": "not_delivered",
- "destination": {
- "id": "DS4M1T6RW9KXPA",
- "name": "ops-channel"
}, - "loudness": "quiet",
- "mentions": [ ],
- "error": "channel_not_found"
}, - {
- "id": "TEK7M3QX9P2R07",
- "at": "2026-10-03T09:17:00Z",
- "kind": "system",
- "actor": {
- "kind": "system",
- "reason": "ingestion"
}, - "system_event": "fallback_template_used",
- "detail": "Root message template failed: line 4: unknown function \"tojson\""
}
], - "next_cursor": null
}Alert Groups of the same Route with the same Group key values, newest first.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "status": "firing",
- "started_at": "2019-08-24T14:15:22Z",
- "duration_seconds": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}
}
], - "next_cursor": "string"
}| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "items": [
- {
- "destination": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}, - "state": "pending",
- "thread_not_attached": true,
- "possible_duplicate": true,
- "past_edit_window": true,
- "error": "string",
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}From firing or snoozed: the caller becomes the Owner and a Snooze ends. By the current Owner it changes nothing (outcome unchanged). By another user it is a Takeover: ownership moves, a Loud event mentions the previous Owner. A Personal access token acts as its User and may; a Service account token cannot become an Owner and is refused with 409 command-refused and the code owner_must_be_user. Other refusals: already_resolved.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}Allowed to every user with the Permission, not only the Owner. The Alert Group becomes firing without an Owner. Refused with the code not_acknowledged.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}Resolves by the user, with an optional Note recorded in the same request. Refused with the code already_resolved.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| note | string [ 1 .. 4000 ] characters Optional Note recorded in the same request. |
{- "note": "string"
}{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}Only for an Alert Group a person resolved; messengers never offer it. Refused, in this order, with the codes not_resolved, resolved_automatically, route_deleted, newer_alert_group_exists (see related_alert_group) and all_alerts_resolved.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}A Snooze until a future time (until), with no end (no_end: true) or until a Snooze preset (preset), chosen explicitly. A preset's end is computed when the Command runs and stored as an instant. Allowed from firing, acknowledged and snoozed.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| until | string <date-time> A future time. |
| no_end | boolean Value: true Snooze until someone unsnoozes it. |
| preset | string (SnoozePreset) Enum: "tomorrow" "week_start" A Snooze preset. |
| time_zone | string IANA time zone in which the end of |
{- "until": "2026-10-04T08:00:00Z"
}{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}The Alert Group becomes firing without an Owner. Refused with the code not_snoozed.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}Notes are kept as long as the Alert Group's summary row (retention.alert_group_summaries), also after its Alerts and Timeline were removed by retention, and are deleted with the summary row.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "body": "string",
- "author": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "transport": "ui",
- "created_at": "2019-08-24T14:15:22Z"
}
], - "next_cursor": "string"
}Adds a Note. Service accounts may add Notes; the author is shown as the Service account.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
| body required | string [ 1 .. 4000 ] characters At most |
{- "body": "string"
}{- "id": "AGK7M3QX9P2RTA",
- "body": "string",
- "author": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "transport": "ui",
- "created_at": "2019-08-24T14:15:22Z"
}Owner only. Recorded in the Timeline like a press in a messenger; it does not reset the Reminder interval. Refused with 409 command-refused and the codes not_owner, no_reminder_pending and, for a Service account token, owner_must_be_user.
| alert_group_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Alert Group |
{- "outcome": "done",
- "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0,
- "title": "string",
- "summary": "string",
- "status": "firing",
- "owner": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "snooze_until": "2019-08-24T14:15:22Z",
- "snoozed_by": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "severity_level": "critical",
- "urgent": true,
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "integrations": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "started_at": "2019-08-24T14:15:22Z",
- "resolved_at": "2019-08-24T14:15:22Z",
- "last_changed_at": "2019-08-24T14:15:22Z",
- "reopen_count": 0,
- "firing_alert_count": 0,
- "resolved_alert_count": 0,
- "resolution": {
- "by": "user",
- "actor": {
- "kind": "user",
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "login": "string",
- "deactivated": true
}, - "reason": "string",
- "reason_code": "resolved"
}, - "unclaimed": true,
- "next_notice": {
- "kind": "ack_timeout",
- "at": "2019-08-24T14:15:22Z"
}, - "delivery_problem": true,
- "details_removed": true,
- "group_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_labels": {
- "property1": "string",
- "property2": "string"
}, - "common_annotations": {
- "property1": "string",
- "property2": "string"
}, - "label_values": {
- "property1": "string",
- "property2": "string"
}, - "notices": [
- {
- "kind": "alerts_still_firing",
- "count": 0,
- "label": "string",
- "retention_days": 0,
- "resolved_number": 0,
- "related_alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}
}
], - "links": [
], - "allowed_commands": [
- "acknowledge"
]
}
}Acknowledge, Resolve, Snooze or Unsnooze on up to alert_group.bulk_max Alert Groups. Each goes through the dispatcher on its own, with its own Audit log and Timeline entry; a refusal never stops the others. Bulk Acknowledge skips Alert Groups another user owns and never makes a Takeover. x-permission lists alternatives: the caller needs the Permission of the chosen command (acknowledge needs alert-groups:acknowledge, resolve needs alert-groups:resolve, snooze and unsnooze need alert-groups:snooze). A bulk Snooze with a preset computes its end once, so every Alert Group gets the same end; the pointers of its problems start with /snooze.
| command required | string Enum: "acknowledge" "resolve" "snooze" "unsnooze" |
| alert_group_ids required | Array of strings (PublicId) [ 1 .. 100 ] items [ items^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... ] At most |
| note | string <= 4000 characters For |
object (SnoozeRequest) Required for |
{- "command": "snooze",
- "alert_group_ids": [
- "AGK7M3QX9P2RTA",
- "AGC71D0EH5MXQB"
], - "snooze": {
- "until": "2026-10-04T08:00:00Z"
}
}{- "results": [
- {
- "alert_group_id": "AGK7M3QX9P2RTA",
- "number": 412,
- "outcome": "done"
}, - {
- "alert_group_id": "AGC71D0EH5MXQB",
- "number": 415,
- "outcome": "refused",
- "code": "already_resolved",
- "message": "already resolved"
}, - {
- "alert_group_id": "AG51BE90Y6KTRW",
- "number": 417,
- "outcome": "skipped",
- "code": "owned_by_other",
- "message": "skipped: owned by Alice"
}, - {
- "alert_group_id": "AGX0000000000Z",
- "number": null,
- "outcome": "failed",
- "code": "not_found",
- "message": "not found"
}
]
}The end that a Snooze with each Snooze preset would set now, in the order tomorrow, week_start, computed like the Snooze itself from organization.workday_start and organization.week_start on the business clock. The time zone is time_zone when given, else the profile time zone of the User the caller acts as, else the Organization's; the answer names the one it used. A time zone Muster does not know (or Local) is 422 invalid_format at /query/time_zone. It reads and changes nothing else.
| time_zone | string Example: time_zone=Europe/Berlin IANA time zone of the ends; defaults to the caller's profile time zone, else the Organization's. |
{- "time_zone": "Europe/Berlin",
- "workday_start": "09:00",
- "week_start": "monday",
- "items": [
- {
- "preset": "tomorrow",
- "until": "2026-10-20T07:00:00Z"
}, - {
- "preset": "week_start",
- "until": "2026-10-26T08:00:00Z"
}
]
}Server-sent events (text/event-stream). OpenAPI 3.1 cannot type event streams, so the events are described by HintEvent.
Each event has the name hint, an id line and a JSON data line {type, id}. A hint carries no data: the client re-reads through the API, so authorization stays in one place. The stream starts with retry: 3000 (the reconnect delay in milliseconds) and a comment line (: keepalive) follows periodically. After a reconnect the client invalidates everything; Last-Event-ID is not replayed. When the session expires or is ended, the server closes the stream; the browser's reconnect then gets 401, which makes EventSource stop for good, and the SPA goes to the sign-in page. The stream follows a web session; a token gets 403 (session_required).
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| type | string (ConnectionType) Enum: "mattermost" "telegram" "bridge" Filter by type. |
{- "items": [
- {
- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "bot_token_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "bot_username": "string",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "destination_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}type selects Mattermost, Telegram or Bridge. The bot token and the push secret are write-only Secrets.
| type required | string |
| name required | string non-empty |
| server_url required | string <uri> |
required | object (Limiter) A rate limit of |
| bot_token | string <password> Write-only Secret. Omit on update to keep the stored one. |
required | object (ProxyConfigInput) Per-client proxy as written. Omitting |
{- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "bot_token": "pa$$word",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password": "string"
}
}{- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "bot_token_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "bot_username": "string",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "destination_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Checks a draft of a Connection of any type, as its form holds it — the address, the bot token typed in the form, the proxy and, for a Bridge, the event delivery mode — with the steps and step codes of checkConnection, and stores nothing: no Connection, no bot name, no info, no Audit log entry. Which token goes where: a bot_token in the draft is sent to the address in the draft; without one, the stored token of connection_id is sent only when the draft's address, normalized as a save normalizes it, and its proxy are the saved ones; otherwise only the dry probe of the type runs, without any token, and the other steps are reported skipped — Mattermost GET <server_url>/api/v4/system/ping, Telegram GET <bot_api_base_url>/bot0:x/getMe, a Bridge GET <base_url>/v1/info. A stored proxy password is used only with the saved proxy type and address. A connection_id that names no Connection, a deleted one or one of another type answers 422 unknown_id at /connection_id; an address or a proxy that a save would refuse answers 422 at its pointer. Runs on the interactive path: a draft with a connection_id takes its limiter token from that Connection, and when none is free within delivery.interactive_budget the answer is 503 with Retry-After; a draft of a new Connection has no limiter and waits for none.
| type required | string |
| server_url required | string <uri> The server URL as |
| bot_token | string <password> A bot token typed in the form, sent only to |
object (ProxyConfigInput) Per-client proxy as written. Omitting | |
| connection_id | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... The saved Mattermost Connection that the form edits; omit it for a new one. An omitted |
{- "type": "mattermost",
- "bot_token": "pa$$word",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password": "string"
}, - "connection_id": "AGK7M3QX9P2RTA"
}{- "ok": true,
- "steps": [
- {
- "name": "token",
- "ok": true,
- "skipped": true,
- "latency_ms": 0,
- "via": "direct",
- "message": "string",
- "code": "token_invalid"
}
], - "warnings": [
- "press_answers_in_thread"
], - "bot_name": "string",
- "webhook_set": true,
- "pending_updates": 0,
- "info": {
- "protocol_version": "1",
- "bridge": {
- "name": "string",
- "version": "string"
}, - "messenger": {
- "name": "string"
}, - "capabilities": {
- "buttons": {
- "max_per_message": 2,
- "max_per_row": 1,
- "data_max_bytes": 64,
- "styles": [
- "primary"
]
}, - "thread_messages": "all",
- "direct_messages": {
- "bot_can_start": true
}, - "private_answers": [
- "ephemeral"
], - "native_mentions": true,
- "quiet_messages": true,
- "status_color": true,
- "delete": {
- "max_age_seconds": 1
}, - "deletion_events": true
}, - "limits": {
- "max_body_length": 500,
- "edit_max_age_seconds": 300,
- "send_per_second_per_channel": 1,
- "send_per_second": 1
}, - "user_lookup": "email",
- "event_delivery": [
- "poll"
], - "link_url_template": "string"
}, - "request_log_run": "AGK7M3QX9P2RTA"
}| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
{- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "bot_token_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "bot_username": "string",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "destination_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one. An omitted Secret field keeps the stored Secret.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| type required | string |
| name required | string non-empty |
| server_url required | string <uri> |
required | object (Limiter) A rate limit of |
| bot_token | string <password> Write-only Secret. Omit on update to keep the stored one. |
required | object (ProxyConfigInput) Per-client proxy as written. Omitting |
{- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "bot_token": "pa$$word",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password": "string"
}
}{- "type": "mattermost",
- "name": "string",
- "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "bot_token_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}, - "bot_username": "string",
- "proxy": {
- "enabled": true,
- "type": "http",
- "address": "string",
- "username": "string",
- "password_status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
}, - "destination_count": 0,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}A Connection used by Destinations cannot be deleted: 409 (in_use). Deleted Destinations do not count; deleting the Connection abandons the final edits still pending for them, which end as Not delivered.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Mattermost verifies the token and returns the bot's name. Telegram works in steps and reports the latency and path of each: a dry probe without the token, getMe, getWebhookInfo. With base_url in the body only the dry probe runs against that unsaved address, without the token: a stored token is sent only to the saved address of its Connection, through its saved proxy; checkConnectionDraft checks an unsaved address with the token typed again. A Bridge Connection is checked in two steps: info calls getInfo of the Bridge protocol with the token, and a passing info is stored on the Connection and returned as info; event_delivery checks that the bridge offers the Connection's event delivery mode. Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| base_url | string or null An unsaved Telegram Bot API base URL. When set, only the dry probe runs against it, without the token: a stored token is sent only to the saved address of its Connection. Kept for API clients; |
{- "base_url": "string"
}{- "ok": true,
- "steps": [
- {
- "name": "token",
- "ok": true,
- "skipped": true,
- "latency_ms": 0,
- "via": "direct",
- "message": "string",
- "code": "token_invalid"
}
], - "warnings": [
- "press_answers_in_thread"
], - "bot_name": "string",
- "webhook_set": true,
- "pending_updates": 0,
- "info": {
- "protocol_version": "1",
- "bridge": {
- "name": "string",
- "version": "string"
}, - "messenger": {
- "name": "string"
}, - "capabilities": {
- "buttons": {
- "max_per_message": 2,
- "max_per_row": 1,
- "data_max_bytes": 64,
- "styles": [
- "primary"
]
}, - "thread_messages": "all",
- "direct_messages": {
- "bot_can_start": true
}, - "private_answers": [
- "ephemeral"
], - "native_mentions": true,
- "quiet_messages": true,
- "status_color": true,
- "delete": {
- "max_age_seconds": 1
}, - "deletion_events": true
}, - "limits": {
- "max_body_length": 500,
- "edit_max_age_seconds": 300,
- "send_per_second_per_channel": 1,
- "send_per_second": 1
}, - "user_lookup": "email",
- "event_delivery": [
- "poll"
], - "link_url_template": "string"
}, - "request_log_run": "AGK7M3QX9P2RTA"
}Mattermost Connections only; loads the team and channel pickers through the bot. A Telegram or Bridge Connection answers 409: the Bridge protocol has no channel list, the Admin enters the channel id. Requires connections:write because it calls out with the bot token. Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Connection |
| team_id | string Only this team. |
| q | string Match on channel name. |
{- "items": [
- {
- "id": "string",
- "name": "string",
- "display_name": "string",
- "team_id": "string",
- "team_name": "string",
- "type": "open",
- "archived": true
}
]
}All types, with health. Outgoing webhook URL and header templates are shown with Secret references only.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| type | string (DestinationType) Enum: "mattermost" "telegram" "webhook" "bridge" Filter by type. |
| health | string (HealthState) Enum: "healthy" "broken" Filter by health. |
| route | string Only Destinations of this Route ( |
{- "items": [
- {
- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "routes": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "created_at": "2019-08-24T14:15:22Z",
- "etag": "string",
- "team_name": "string",
- "channel_name": "string"
}
], - "next_cursor": "string"
}type selects Mattermost, Telegram, outgoing webhook or Bridge. Saving a Mattermost, Telegram or Bridge Destination runs the Destination check through the interactive path and refuses one that fails it with 422 validation-failed and destination_check_failed. Creating an outgoing webhook Destination also generates its Signing secret, returned once in signing_secret (null for the other types). Routes attach Destinations through destination_ids.
| type required | string |
| name required | string non-empty |
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| team_id required | string |
| channel_id required | string |
required | object (MentionSettings) Keyed by the Mention names of Loud events. Reminders and auto-unacknowledge always mention the Owner, Takeovers the previous Owner. |
required | object (Limiter) A rate limit of |
{- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}
}{- "destination": {
- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "routes": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "created_at": "2019-08-24T14:15:22Z",
- "etag": "string",
- "team_name": "string",
- "channel_name": "string"
}, - "signing_secret": "string"
}| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "routes": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "created_at": "2019-08-24T14:15:22Z",
- "etag": "string",
- "team_name": "string",
- "channel_name": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one. An omitted Secret field keeps the stored Secret. null on a proxy password clears it. Saving a Mattermost, Telegram or Bridge Destination runs the Destination check as createDestination does and refuses a failing one with destination_check_failed.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| type required | string |
| name required | string non-empty |
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| team_id required | string |
| channel_id required | string |
required | object (MentionSettings) Keyed by the Mention names of Loud events. Reminders and auto-unacknowledge always mention the Owner, Takeovers the previous Owner. |
required | object (Limiter) A rate limit of |
{- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}
}{- "type": "mattermost",
- "name": "string",
- "connection_id": "AGK7M3QX9P2RTA",
- "team_id": "string",
- "channel_id": "string",
- "mentions": {
- "new_alert_group": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "new_alerts": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "reopen": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "ack_timeout": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "snooze_ended": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}, - "rise_to_urgent": {
- "everyone": "none",
- "user_ids": [
- "AGK7M3QX9P2RTA"
], - "groups": [
- "string"
]
}
}, - "limiter": {
- "limit": 1,
- "per_seconds": 1
}, - "id": "AGK7M3QX9P2RTA",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "routes": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}
], - "template_error": {
- "since": "2019-08-24T14:15:22Z",
- "error": "string",
- "fallback": "fallback_template"
}, - "created_at": "2019-08-24T14:15:22Z",
- "etag": "string",
- "team_name": "string",
- "channel_name": "string"
}Always allowed: the Destination leaves every Route, and open Root messages get one final edit "No longer updated here" and nothing after; then the Destination's secrets are wiped. An outgoing webhook in events mode has no Root message: its queued events are abandoned and end as Not delivered, no final event is sent, and its secrets are wiped at once (in mode both, after the final edits of the template mode). It is a soft delete: the Destination is kept for history and no longer counts as using its Connection. There is no 409; a stale If-Match is 412.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Verifies that Muster can still reach and post to the Destination without sending a message: Mattermost token and channel membership; Telegram getChat for the channel, its discussion group from linked_chat_id, and getChatMember for the bot in both; Bridge checkChannel. A success ends the Broken state. Not available for outgoing webhooks (422 with check_not_supported). Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "ok": true,
- "checks": [
- {
- "name": "token",
- "ok": true,
- "message": "string",
- "code": "token_invalid"
}
], - "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "request_log_run": "AGK7M3QX9P2RTA"
}One "create" request marked "Test message", built from a recent Alert Group of one of the Destination's Routes or from a built-in example, through the interactive path. An outgoing webhook sends the test event in events mode and the "create" request in template mode, both when it uses both. Secrets and the Signing secret are masked in the result. Test messages are never reconciled and change no Alert Group. A successful test of a Broken Destination ends the Broken state. Audited. A step that could not get a limiter token in time ends with error_class limited. A Bridge Destination posts one test message of the kind test with postMessage.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
required | object (TestSource) |
{- "source": {
- "kind": "alert_group",
- "alert_group_id": "string"
}
}{- "steps": [
- {
- "name": "message",
- "request": {
- "method": "string",
- "url": "string",
- "headers": [
- {
- "name": "string",
- "value": "string"
}
], - "body": "string"
}, - "response_status": 0,
- "response_body": "string",
- "extracted": {
- "property1": "string",
- "property2": "string"
}, - "duration_ms": 0,
- "error_class": "none",
- "error": "string",
- "error_code": "press_not_reached"
}
], - "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}, - "request_log_run": "AGK7M3QX9P2RTA"
}Renders the Root message or the webhook requests for a chosen Alert Group or the example without sending anything. For a Bridge Destination the item message is the envelope as Muster would post it, as JSON (format json).
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
required | object (TestSource) |
{- "source": {
- "kind": "alert_group",
- "alert_group_id": "string"
}
}{- "items": [
- {
- "name": "message",
- "format": "markdown",
- "text": "string",
- "request": {
- "method": "string",
- "url": "string",
- "headers": [
- {
- "name": "string",
- "value": "string"
}
], - "body": "string"
}
}
]
}Names with set and the time of the last change. Values are never returned. 409 (not_webhook_destination) for a Destination that is not an outgoing webhook.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "items": [
- {
- "name": "string",
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}
]
}Creates or replaces the named Secret, referenced as {{ .Secrets.<name> }}. If-Match, when given, is compared with the ETag of listDestinationSecrets.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
| secret_name required | string^[A-Za-z_][A-Za-z0-9_]*$ Name of a Destination Secret. |
| If-Match | string Optional ETag; when present and stale, the request gets |
| value required | string Write-only Secret. |
{- "value": "string"
}{- "name": "string",
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z"
}If-Match, when given, is compared with the ETag of listDestinationSecrets.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
| secret_name required | string^[A-Za-z_][A-Za-z0-9_]*$ Name of a Destination Secret. |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}409 (not_webhook_destination) for a Destination that is not an outgoing webhook.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "set": true,
- "updated_at": "2019-08-24T14:15:22Z",
- "previous_active_since": "2019-08-24T14:15:22Z"
}The first Signing secret is generated when the Destination is created. This returns a new one, once; requests then carry signatures with both the new and the previous secret until retirePreviousSigningSecret.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "secret": "string",
- "status": {
- "set": true,
- "updated_at": "2019-08-24T14:15:22Z",
- "previous_active_since": "2019-08-24T14:15:22Z"
}
}409 (not_webhook_destination) for a Destination that is not an outgoing webhook.
| destination_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Destination |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
], - "id": "AGK7M3QX9P2RTA",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}| name required | string non-empty Unique in the Organization; Link rule templates call |
| description | string |
| columns required | Array of strings non-empty unique [ items non-empty ] Column names, unique within the table. |
required | Array of objects (LookupEntry) Rows. The keys of |
{- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
]
}{- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
], - "id": "AGK7M3QX9P2RTA",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| lookup_table_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Lookup table |
{- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
], - "id": "AGK7M3QX9P2RTA",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one. A new name for a table that the URL template of a Link rule reads by its name is refused with 409 (in_use), link_rules naming the rules, since they would read nothing.
| lookup_table_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Lookup table |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty Unique in the Organization; Link rule templates call |
| description | string |
| columns required | Array of strings non-empty unique [ items non-empty ] Column names, unique within the table. |
required | Array of objects (LookupEntry) Rows. The keys of |
{- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
]
}{- "name": "string",
- "description": "string",
- "columns": [
- "string"
], - "entries": [
- {
- "key": "string",
- "values": {
- "property1": "string",
- "property2": "string"
}
}
], - "id": "AGK7M3QX9P2RTA",
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Refused with 409 (in_use) while the URL template of a Link rule reads the table by its name, link_rules naming the rules.
| lookup_table_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Lookup table |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
{- "items": [
- {
- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string",
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}
], - "next_cursor": "string"
}| name required | string non-empty |
required | Array of objects (Matcher) |
required | object (LinkRuleScope) |
| url_template required | string Go template that may call |
{- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string"
}{- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string",
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}| link_rule_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Link rule |
{- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string",
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}Replaces the writable fields. Requires If-Match; a stale ETag gets 412. An omitted optional field keeps its stored value; an explicit null clears a nullable one.
| link_rule_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Link rule |
| If-Match required | string ETag of the representation being replaced, as returned by the last read. A mismatch gets |
| name required | string non-empty |
required | Array of objects (Matcher) |
required | object (LinkRuleScope) |
| url_template required | string Go template that may call |
{- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string"
}{- "name": "string",
- "matchers": [
- {
- "label": "string",
- "op": "=",
- "value": "string"
}
], - "scope": {
- "type": "alert_group",
- "label": "string"
}, - "url_template": "string",
- "id": "AGK7M3QX9P2RTA",
- "builtin": true,
- "created_at": "2019-08-24T14:15:22Z",
- "etag": "string"
}The built-in "Explore" rule cannot be deleted (409).
| link_rule_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Link rule |
| If-Match | string Optional ETag; when present and stale, the request gets |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Parses and renders a template in the sandbox against a recent Stored Snapshot, an Alert Group or a built-in example. Template errors are returned in errors with their position, not as a Problem, so an editor can show them next to the preview.
| kind required | string (TemplateKind) Enum: "root_message" "line" "ack_timeout_notice" "link_rule" "webhook_request" |
| template required | string The template to render; empty renders what a Route without a template of the kind shows, and the result returns the source of the built-in template. |
| format | string or null Enum: "markdown" "html" "commonmark" null The markup the output is laid out in and alert data are escaped for — |
| route_id | string or null (NullablePublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... A |
| stored_snapshot_id | string or null A recent Stored Snapshot as the sample. Without a sample the most recent ones the Route took are used ( |
| alert_group_id | string or null (NullablePublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... A |
| language | string or null (NullableLanguage) Enum: "en" "ru" null UI or template language; null follows the default. |
| length_limit | integer or null >= 1 Messenger length limit to apply, for example 4096. |
{- "kind": "root_message",
- "template": "string",
- "format": "markdown",
- "route_id": "AGK7M3QX9P2RTA",
- "stored_snapshot_id": "string",
- "alert_group_id": "AGK7M3QX9P2RTA",
- "language": "en",
- "length_limit": 1
}{- "valid": true,
- "output": "string",
- "truncated": true,
- "format": "markdown",
- "source": "string",
- "sample": "stored_snapshot",
- "errors": [
- {
- "pointer": "string",
- "code": "string",
- "detail": "string",
- "line": 1,
- "column": 1,
- "check_code": "token_invalid"
}
]
}Service account tokens get 403 (service_account_not_allowed).
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "messenger": "telegram",
- "connection": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "external_id": "string",
- "username": "string",
- "display_name": "string",
- "last_used_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}The profile's own short list of the Connections that are not deleted, for picking one when linking a messenger account. It needs no Permission, independently of connections:read, and shows only the id, the name and the messenger of each Connection, and for a Bridge Connection how an account can be linked through it — link_methods and handle_kind, from the Connection's last info. Service account tokens get 403 (service_account_not_allowed).
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "messenger": "telegram",
- "link_methods": [
- "token"
], - "handle_kind": "email"
}
]
}Unlinks one of the caller's own messenger accounts. Web session only: a token gets 403 (session_required).
| account_link_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Account link id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}Returns a deep link t.me/<bot>?start=<token>; the token is single-use, valid for account_link.telegram_token_ttl. Pressing Start in Telegram completes the link and arrives as an account-links hint with the link's public_id. Only the signed-in web session can start a link (not a token). No operation starts a link for another User, whatever the caller's Role. A connection_id that names no Telegram Connection — missing, deleted or a Mattermost one — answers 422 unknown_id at /connection_id. When the bot's username is not known from the last Connection check, it is read with getMe on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After, and when Telegram refuses the call, 409.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
{- "connection_id": "AGK7M3QX9P2RTA"
}{- "expires_at": "2019-08-24T14:15:22Z"
}The Connection's bot sends a direct message with a code to the @username. Code requests are limited per requesting User and per target account (429 link_code_requests_exceeded with Retry-After). Refused with 409 if the account is already linked to another user (account_linked_elsewhere), or without a code when Mattermost refuses a call. Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After. No operation starts a link for another User, whatever the caller's Role. A connection_id that names no Mattermost Connection — missing, deleted or a Telegram one — answers 422 unknown_id at /connection_id; a username the Mattermost server does not know answers 422 messenger_user_not_found at /username.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| username required | string The |
{- "connection_id": "AGK7M3QX9P2RTA",
- "username": "string"
}{- "request_id": "AGK7M3QX9P2RTA",
- "expires_at": "2019-08-24T14:15:22Z",
- "attempts_remaining": 0
}At most 5 attempts; after that the code is void. A wrong code, and a request that is void, used or expired, answer 422 link_code_invalid at /code, never saying which, with attempts_remaining: the codes the request still takes, 0 once it takes none; a request of another User is 404. Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After. No operation starts a link for another User, whatever the caller's Role.
| request_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| code required | string The code the bot sent as a direct message. |
{- "request_id": "AGK7M3QX9P2RTA",
- "code": "string"
}{- "id": "AGK7M3QX9P2RTA",
- "messenger": "telegram",
- "connection": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "external_id": "string",
- "username": "string",
- "display_name": "string",
- "last_used_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}Returns a token to send to the bot of the Bridge Connection in a direct message: 32 random bytes in base64url, single-use, valid for account_link.bridge_token_ttl and bound to the User and the Connection. When the Connection's last info has a link_url_template, link_url is that template with the token in place of {token}, kept only when it is an absolute http or https link; otherwise it is null. The bridge reports the token with an account_link event, which completes the link and arrives as an account-links hint with the link's public_id. Only the signed-in web session can start a link (not a token). No operation starts a link for another User, whatever the caller's Role. A connection_id that names no Bridge Connection — missing, deleted or of another type — answers 422 unknown_id at /connection_id. Calls no bridge.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
{- "connection_id": "AGK7M3QX9P2RTA"
}{- "token": "string",
- "expires_at": "2019-08-24T14:15:22Z"
}Where the Bridge Connection's info declares direct_messages with bot_can_start and a user_lookup other than none, the bridge finds the account with the handle the caller entered — of the kind user_lookup declares — with findUsers, and its bot sends a code with sendDirectMessage. Code requests are limited per requesting User and per target account (429 link_code_requests_exceeded with Retry-After, account_link.bridge_code_requests); a request whose direct message failed still counts. Refused with 409 code_not_offered when the Connection's info, read again first when Muster's copy is older than bridge.info_max_age, offers no code or has never been read; with 409 account_linked_elsewhere when the account is linked to another User; and with 409 without a code when the bridge refuses a call. Runs on the interactive path: when no limiter token is free within delivery.interactive_budget, the answer is 503 with Retry-After. No operation starts a link for another User, whatever the caller's Role. A connection_id that names no Bridge Connection answers 422 unknown_id at /connection_id; a handle the bridge does not find answers 422 handle_not_found at /handle, and an account the bot cannot write to 422 direct_message_refused at /handle.
| connection_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| handle required | string [ 1 .. 320 ] characters The handle of the account to link, of the kind the Connection's |
{- "connection_id": "AGK7M3QX9P2RTA",
- "handle": "string"
}{- "request_id": "AGK7M3QX9P2RTA",
- "expires_at": "2019-08-24T14:15:22Z",
- "attempts_remaining": 0
}At most 5 attempts (account_link.bridge_code); after that the code is void. A wrong code, and a request that is void, used or expired or whose Connection was deleted, answer 422 link_code_invalid at /code, never saying which, with attempts_remaining: the codes the request still takes, 0 once it takes none; a request of another User, or one that is not a Bridge code request, is 404. The link stores the account's external_id, display_name and handle as the bridge reported them. No direct message confirms it, and no bridge is called. No operation starts a link for another User, whatever the caller's Role.
| request_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Opaque public identifier ( |
| code required | string The code the bot sent as a direct message. |
{- "request_id": "AGK7M3QX9P2RTA",
- "code": "string"
}{- "id": "AGK7M3QX9P2RTA",
- "messenger": "telegram",
- "connection": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "external_id": "string",
- "username": "string",
- "display_name": "string",
- "last_used_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "messenger": "telegram",
- "connection": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "external_id": "string",
- "username": "string",
- "display_name": "string",
- "last_used_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z"
}
]
}Admins can remove any link but cannot create one for someone else. An Admin's own link is removed from the web session only; with a token the answer is 403 (session_required).
| user_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA User |
| account_link_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Account link id. |
{- "title": "Unauthenticated",
- "status": 401,
- "detail": "The token is missing, wrong or expired.",
- "instance": "/api/v1/routes"
}The recent HTTP requests Muster sent for a Connection or an outgoing webhook Destination, each attempt with its answer and masked, kept for request_log.max_age and to the newest request_log.max_records of each owner (C-23).
The records of exactly one owner, or of one check run, newest first: connection lists every record of a Connection, destination every record of an outgoing webhook Destination or, for a messenger Destination, the records of its Connection that name it; run alone lists the records of that check run whose owner is a Connection or nobody — the checks before saving of new Connections — and beside an owner it narrows that owner's list. Neither an owner nor a run, or both owners, answer 422 with the code one_of_required. The caller needs connections:read to name a Connection or a run alone and destinations:read to name a Destination (403 otherwise); an unknown or deleted owner is 404. Only records newer than request_log.max_age and among the newest request_log.max_records of their owner are listed — a messenger Destination's within its Connection's — so a list never shows more than that bound. Each record is one attempt of a request: its URL as errors show it, its status, latency and path, without headers or bodies, which getRequestRecord reads.
| cursor | string Opaque cursor from |
| limit | integer [ 1 .. 500 ] Default: 50 Page size ( |
| connection | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: connection=AGK7M3QX9P2RTA The Connection whose records are listed, by |
| destination | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: destination=AGK7M3QX9P2RTA The Destination whose records are listed, by |
| direction | string (RequestDirection) Enum: "outbound" "inbound" Only the requests Muster sent ( |
| status_class | string Enum: "2xx" "3xx" "4xx" "5xx" "none" Only the records whose answer has a status of this class, or, with |
| operation | string [ 1 .. 64 ] characters Only the records of this operation, such as |
| alert_group | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: alert_group=AGK7M3QX9P2RTA Only the records of the deliveries of this Alert Group, by |
| run | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: run=AGK7M3QX9P2RTA Only the records of this check run ( |
{- "items": [
- {
- "id": "AGK7M3QX9P2RTA",
- "at": "2019-08-24T14:15:22Z",
- "direction": "outbound",
- "operation": "string",
- "method": "string",
- "url": "string",
- "status": 0,
- "latency_ms": 0,
- "via": "direct",
- "attempt": 1,
- "error_class": "retry_after",
- "error_code": "dns_failed",
- "check": "connection_check",
- "check_run": "AGK7M3QX9P2RTA",
- "connection_id": "AGK7M3QX9P2RTA",
- "destination": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}, - "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}, - "request_body_truncated": true,
- "response_body_truncated": true
}
], - "next_cursor": "string"
}One record with its headers and bodies, masked. The caller needs the Permission of the record's owner, connections:read for a Connection's record — even one listed through a messenger Destination with destinations:read — and destinations:read for an outgoing webhook's (403 otherwise). A record past request_log.max_age or past the newest request_log.max_records of its owner, or whose owner is deleted, is 404, as it is in no list. Headers, bodies and the error are untrusted text.
| request_record_id required | string (PublicId) ^[A-HJKMNP-TV-Za-hjkmnp-tv-z]{1,2}[0-9A-TV-Za... Example: AGK7M3QX9P2RTA Record of the Request log, by |
{- "id": "AGK7M3QX9P2RTA",
- "at": "2019-08-24T14:15:22Z",
- "direction": "outbound",
- "operation": "string",
- "method": "string",
- "url": "string",
- "status": 0,
- "latency_ms": 0,
- "via": "direct",
- "attempt": 1,
- "error_class": "retry_after",
- "error_code": "dns_failed",
- "check": "connection_check",
- "check_run": "AGK7M3QX9P2RTA",
- "connection_id": "AGK7M3QX9P2RTA",
- "destination": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string",
- "type": "mattermost",
- "health": {
- "state": "healthy",
- "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
}, - "alert_group": {
- "id": "AGK7M3QX9P2RTA",
- "number": 0
}, - "request_body_truncated": true,
- "response_body_truncated": true,
- "request_headers": {
- "property1": [
- "string"
], - "property2": [
- "string"
]
}, - "request_body": "string",
- "request_body_bytes": 0,
- "response_headers": {
- "property1": [
- "string"
], - "property2": [
- "string"
]
}, - "response_body": "string",
- "response_body_bytes": 0,
- "error": "string"
}"Recovering after downtime" for every signed-in user, "no replica is leading" for Admins. Changes arrive as system-notices hints.
{- "items": [
- {
- "kind": "recovering_after_downtime",
- "audience": "all",
- "since": "2019-08-24T14:15:22Z",
- "until": "2019-08-24T14:15:22Z"
}
]
}Read-only: replicas and the Leader with their key ids, the recovery state, delivery queues, Broken Destinations, Integrations with Heartbeat lost or truncated Snapshots, template errors, active Storms and the last outgoing heartbeat.
{- "version": "string",
- "commit": "string",
- "replicas": [
- {
- "id": "string",
- "leader": true,
- "key_ids": [
- "string"
], - "refreshed_at": "2019-08-24T14:15:22Z"
}
], - "recovery": {
- "active": true,
- "period_from": "2019-08-24T14:15:22Z",
- "period_to": "2019-08-24T14:15:22Z",
- "until": "2019-08-24T14:15:22Z"
}, - "delivery_queues": [
- {
- "destination": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "queued": 0
}
], - "broken_destinations": [
- {
- "destination": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "since": "2019-08-24T14:15:22Z",
- "reason": "string"
}
], - "integrations_attention": [
- {
- "integration": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "issue": "heartbeat_lost",
- "since": "2019-08-24T14:15:22Z"
}
], - "template_errors": [
- {
- "subject_kind": "route",
- "subject": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "template": "root_message",
- "since": "2019-08-24T14:15:22Z",
- "error": "string"
}
], - "active_storms": [
- {
- "route": {
- "id": "AGK7M3QX9P2RTA",
- "name": "string"
}, - "since": "2019-08-24T14:15:22Z",
- "alert_group_count": 0
}
], - "outgoing_heartbeat": {
- "configured": true,
- "last_attempt_at": "2019-08-24T14:15:22Z",
- "last_ok": true,
- "last_error": "string",
- "last_error_class": "transient",
- "last_status": 0
}
}Liveness, readiness and metrics on the internal listener. Hand-written handlers: excluded from the generated server.
Sent by Muster to the URL of an outgoing webhook Destination in events mode: one POST per lifecycle event, in order per Alert Group, at least once.
Every request carries webhook-id, webhook-timestamp and webhook-signature in the style of the Standard Webhooks specification: the signature is
v1,<base64 HMAC-SHA256> over <webhook-id>.<webhook-timestamp>.<body>, with several space-separated signatures while a previous Signing secret
is not yet retired. Receivers drop duplicates by webhook-id. Response mapping: 2xx delivered; 429 or 503 with Retry-After retried exactly as asked;
408, other 5xx, timeouts and network errors retried with backoff; 401, 403, 404 and 410 mark the Destination Broken; 400, 413, 422,
redirects and everything else end that delivery as Not delivered.
| webhook-id required | string Id of this event, kept across retries. |
| webhook-timestamp required | string Unix time in seconds when the request was signed. |
| webhook-signature required | string One or more space-separated |
| version required | integer Value: 1 |
| event required | string (WebhookEventName) Enum: "created" "alerts_added" "alert_replaced" "alert_resolved" "alert_continued" "annotations_changed" "severity_raised" "urgency_raised" "reopened" "snooze_ended" "resolved" "moved_to_default_route" "acknowledged" "takeover" "unacknowledged" "unresolved" "snoozed" "unsnoozed" "note_added" "ack_timeout" "unclaimed" "reminder" "reminder_answered" "auto_unacknowledged" "notices_missed" "test" One of the lifecycle event names (see |
| notify required | boolean True exactly when the event is Loud. |
required | Array of objects (WebhookMentionTarget) |
| sequence required | integer >= 0 The lifecycle event number of the Alert Group, kept across retries. It grows with every lifecycle event of the Alert Group but may have gaps, and for a Destination added to the Route later it does not start at 1; receivers rely only on "greater means newer". 0 on the |
| occurred_at required | string <date-time> |
required | object (WebhookActor) |
required | object (WebhookAlertGroup) The current state of the Alert Group when the event was recorded. |
required | Array of objects (WebhookAlert) One element per Alert, by fingerprint. |
| test | boolean True only on the |
{- "version": 1,
- "event": "created",
- "notify": true,
- "mentions": [
- {
- "type": "user",
- "id": "SR2K9D1VW3MPTE",
- "name": "Alice Smith",
- "login": "alice"
}
], - "sequence": 1,
- "occurred_at": "2026-10-03T09:41:07Z",
- "actor": {
- "kind": "system",
- "reason": "timer"
}, - "alert_group": {
- "number": 412,
- "id": "AGK7M3QX9P2RTA",
- "title": "HighErrorRate payments-api",
- "summary": "Error rate above 5% for 10 minutes",
- "status": "firing",
- "route": {
- "id": "RT9X2QF4H7NJCA",
- "name": "payments-critical"
}, - "urgent": true,
- "severity_level": "critical",
- "started_at": "2026-10-03T09:12:40Z",
- "reopen_count": 0,
}, - "alerts": [
- {
- "fingerprint": "3a1f9c0be2d47a55",
- "status": "firing",
- "labels": {
- "alertname": "HighErrorRate",
- "namespace": "payments",
- "severity": "critical"
}, - "annotations": {
- "summary": "Error rate above 5% for 10 minutes"
}, - "starts_at": "2026-10-03T09:12:40Z",
}
]
}