Skip to content

Send an event

POST
/webhooks
curl --request POST \
--url https://api.mayottehub.com/v1/webhooks \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Mayotte-Signature: v1=<64 lowercase hex characters>' \
--header 'X-Mayotte-Timestamp: 1762862400' \
--data '{ "id": "evt_8f2c1a", "type": "booking.created", "created_at": "2026-11-11T12:00:00Z", "data": {} }'

One event per call, signed with your key’s signing secret: X-Mayotte-Signature is v1= and the lowercase hex HMAC-SHA256 of <timestamp>.<body>, the body exactly as sent. Each event is kept once per key and id. Needs the webhooks scope.

X-Mayotte-Timestamp
required
string
/^[0-9]{9,11}$/

The time you signed, in Unix seconds. Within 5 minutes of our clock.

X-Mayotte-Signature
required
string

v1= and 64 lowercase hex characters. Two, separated by a comma, while you change secrets.

Idempotency-Key
string
<= 200 characters

Your event’s id, when the body has no id.

Media typeapplication/json
object
id
required

Your event’s own id. The same each time you send it again.

string
/^[A-Za-z0-9._:-]{1,200}$/
type
required

What happened.

string
/^[A-Za-z][A-Za-z0-9_.-]{0,99}$/
created_at

When it happened in your system.

string format: date-time
data

Depends on the type; its fields are agreed with Mayotte Hub.

object

The event is kept (or was already kept, then duplicate is true).

Media typeapplication/json
object
ok
required
boolean
id
required
string
duplicate
required

True when this key already sent an event with this id.

boolean

Example

{
"ok": true
}

The body is not a JSON object (bad_json) or has no valid id or type (bad_event).

Media typeapplication/json
object
error
required

Words for a person. They may change.

string
code
required

What your program should read.

string
Allowed values: bad_json bad_event no_key bad_key revoked expired no_timestamp old_timestamp no_signature bad_signature scope ip not_found method too_large rate server unreachable not_ready

Example

{
"code": "bad_json"
}

No key (no_key), a key that is not valid (bad_key), revoked (revoked) or ended (expired); for an event also a missing or old time (no_timestamp, old_timestamp) or a missing or wrong signature (no_signature, bad_signature).

Media typeapplication/json
object
error
required

Words for a person. They may change.

string
code
required

What your program should read.

string
Allowed values: bad_json bad_event no_key bad_key revoked expired no_timestamp old_timestamp no_signature bad_signature scope ip not_found method too_large rate server unreachable not_ready

Example

{
"code": "bad_json"
}

The key may not do this (scope), or the call came from an address it does not allow (ip).

Media typeapplication/json
object
error
required

Words for a person. They may change.

string
code
required

What your program should read.

string
Allowed values: bad_json bad_event no_key bad_key revoked expired no_timestamp old_timestamp no_signature bad_signature scope ip not_found method too_large rate server unreachable not_ready

Example

{
"code": "bad_json"
}

The body is over 1 MB (too_large).

Media typeapplication/json
object
error
required

Words for a person. They may change.

string
code
required

What your program should read.

string
Allowed values: bad_json bad_event no_key bad_key revoked expired no_timestamp old_timestamp no_signature bad_signature scope ip not_found method too_large rate server unreachable not_ready

Example

{
"code": "bad_json"
}

Too many calls (rate). Wait for the retry-after header, in seconds.

Media typeapplication/json
object
error
required

Words for a person. They may change.

string
code
required

What your program should read.

string
Allowed values: bad_json bad_event no_key bad_key revoked expired no_timestamp old_timestamp no_signature bad_signature scope ip not_found method too_large rate server unreachable not_ready

Example

{
"code": "bad_json"
}
retry-after
integer