Skip to content

Replace a webhook endpoint

PUT
/v1/webhooks/{webhookId}
curl --request PUT \
--url https://api.roundrobinbot.eu/v1/webhooks/example \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json-patch+json' \
--header 'If-Match: example' \
--data '{ "name": "example", "url": "example", "eventTypes": [ "example" ] }'

Replaces the endpoint’s name, its URL and its subscriptions together. All three are required: an omitted eventTypes would read as “unsubscribe from everything”, and losing a subscription without being told is indistinguishable from us having stopped delivering. The URL is judged as strictly as at registration, because an edit is otherwise how an address we refuse to call gets in.

webhookId
required
string
If-Match
required
string

The ETag from your last read of this resource, sent back exactly as you received it, quotes included. The write happens only if nothing changed in between: a stale validator is answered 412 and nothing is written. Send * to write against whatever is current on purpose. Omitting the header is 428, never an unconditional write. https://docs.roundrobinbot.eu/api/conventions/#conditional-writes

One of:
null
Examplegenerated
{
"name": "example",
"url": "example",
"eventTypes": [
"example"
]
}

OK

Media typeapplication/json

A registered destination: where Round Robin posts this workspace’s events, what it is subscribed to, and whether we are still calling it. Never the signing secret.

object
id
string
name

What the receiving system is called. Shown in the dashboard, never used for lookup.

string
url

Where we post. Always https.

string
eventTypes

What this endpoint receives: duty.changed, nobody.on_call, rotation.created, rotation.updated, rotation.deleted.

Array<string>
state

enabled or disabled. There is no revoked state: delete the endpoint instead.

string
disabledReason

Why we stopped calling: manual, delivery_failures or plan_downgrade. Absent while the endpoint is enabled.

null | string
currentSecretId

Which secret is signing now, so your logs and ours name the same one.

null | string
currentSecretCreatedAt
null | string format: date-time
previousSecretId

The outgoing secret during a rotation’s grace window, absent at every other time.

null | string
previousSecretExpiresAt

When the outgoing secret stops signing. Until then both signatures travel in one header, so a receiver can cut over without an outage.

null | string format: date-time
createdAt

When the endpoint was registered.

string format: date-time
updatedAt
null | string format: date-time
Examplegenerated
{
"id": "example",
"name": "example",
"url": "example",
"eventTypes": [
"example"
],
"state": "example",
"disabledReason": "example",
"currentSecretId": "example",
"currentSecretCreatedAt": "2026-04-15T12:00:00Z",
"previousSecretId": "example",
"previousSecretExpiresAt": "2026-04-15T12:00:00Z",
"createdAt": "2026-04-15T12:00:00Z",
"updatedAt": "2026-04-15T12:00:00Z"
}

Bad Request

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Unauthorized

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Payment Required

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Forbidden

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Not Found

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Conflict

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Precondition Failed

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}

Precondition Required

Media typeapplication/json
object
type
null | string
title
null | string
status
null | integer | string format: int32
/^-?(?:0|[1-9]\d*)$/
detail
null | string
instance
null | string
Examplegenerated
{
"type": "example",
"title": "example",
"status": 1,
"detail": "example",
"instance": "example"
}