> For the complete documentation index, see [llms.txt](https://docs.ospree.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ospree.io/developers/webhooks/openapi/models.md).

# Models

## The ApiErrorResponse object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiErrorResponse":{"properties":{"status":{"type":"string","title":"Status","default":"error"},"code":{"type":"integer","title":"Code","description":"Duplicates the HTTP status; use `error_code`. Removed in v3."},"message":{"type":"string","title":"Message"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code","description":"Stable, machine-readable error code, e.g. `auth.unauthenticated`. Additive-only."},"data":{"anyOf":[{},{"type":"null"}],"title":"Data"}},"type":"object","required":["code","message"],"title":"ApiErrorResponse","description":"*summary*: Api error response model"}}}}
```

## The ApiFailResponse object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiFailResponse":{"properties":{"status":{"type":"string","title":"Status","default":"fail"},"message":{"type":"string","title":"Message"},"error_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Code","description":"Stable, machine-readable error code, e.g. `auth.unauthenticated`. Additive-only."},"data":{"anyOf":[{},{"type":"null"}],"title":"Data"}},"type":"object","required":["message"],"title":"ApiFailResponse","description":"*summary*: Api fail response model"}}}}
```

## The ApiSuccessResponse\_List\_WebhookConfigurationView\_\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_List_WebhookConfigurationView__":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookConfigurationView"},"type":"array"},{"type":"null"}],"title":"Data"}},"type":"object","title":"ApiSuccessResponse[List[WebhookConfigurationView]]"},"WebhookConfigurationView":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"event_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Names"},"ip_allowlist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ip Allowlist"},"id":{"type":"string","format":"uuid","title":"Id"},"business_id":{"type":"string","format":"uuid","title":"Business Id"},"event_type":{"type":"string","title":"Event Type"},"modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Modified By"},"last_modified":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Modified"},"webhook_desc":{"type":"string","title":"Webhook Desc"}},"type":"object","required":["webhook_url","id","business_id","event_type","webhook_desc"],"title":"WebhookConfigurationView"}}}}
```

## The ApiSuccessResponse\_List\_WebhookEventTypeResponse\_\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_List_WebhookEventTypeResponse__":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"items":{"$ref":"#/components/schemas/WebhookEventTypeResponse"},"type":"array"},{"type":"null"}],"title":"Data"}},"type":"object","title":"ApiSuccessResponse[List[WebhookEventTypeResponse]]"},"WebhookEventTypeResponse":{"properties":{"event_type_name":{"type":"string","title":"Event Type Name"},"event_type_id":{"type":"string","title":"Event Type Id"}},"type":"object","required":["event_type_name","event_type_id"],"title":"WebhookEventTypeResponse"}}}}
```

## The ApiSuccessResponse\_Page\_WebhookRequestResponse\_\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_Page_WebhookRequestResponse__":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"$ref":"#/components/schemas/Page_WebhookRequestResponse_"},{"type":"null"}]}},"type":"object","title":"ApiSuccessResponse[Page[WebhookRequestResponse]]"},"Page_WebhookRequestResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookRequestResponse"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0,"title":"Total"},"page":{"type":"integer","minimum":1,"title":"Page"},"size":{"type":"integer","minimum":1,"title":"Size"},"pages":{"type":"integer","minimum":0,"title":"Pages"}},"type":"object","required":["items","total","page","size","pages"],"title":"Page[WebhookRequestResponse]"},"WebhookRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"request_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Request Id"},"execution_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Count"},"webhook_url":{"type":"string","title":"Webhook Url"},"event_type":{"type":"string","title":"Event Type"},"event_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Name"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"request_payload":{"anyOf":[{},{"type":"null"}],"title":"Request Payload"},"error_details":{"anyOf":[{},{"type":"null"}],"title":"Error Details"}},"type":"object","required":["id","webhook_url","event_type","timestamp"],"title":"WebhookRequestResponse","description":"The commercial delivery-attempt response — the status projection plus the payload.\n\nThe two additions are what makes this a PII-bearing read (see\n``docs/audit/adoption-roster.toml``): an integration token holder gets the\nbody Ospree delivered and the failure detail recorded against it."}}}}
```

## The ApiSuccessResponse\_WebhookConfiguration\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_WebhookConfiguration_":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"$ref":"#/components/schemas/WebhookConfiguration"},{"type":"null"}]}},"type":"object","title":"ApiSuccessResponse[WebhookConfiguration]"},"WebhookConfiguration":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"event_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Names"},"ip_allowlist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ip Allowlist"},"id":{"type":"string","format":"uuid","title":"Id"},"event_type":{"type":"integer","title":"Event Type"},"business_id":{"type":"string","format":"uuid","title":"Business Id"},"created_by":{"type":"string","format":"uuid","title":"Created By"},"created":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created"},"modified_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Modified By"},"last_modified":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Modified"},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret"}},"type":"object","required":["webhook_url","id","event_type","business_id","created_by"],"title":"WebhookConfiguration","description":"What the upsert hands back — with the signing secret only when it minted one.\n\nThe plaintext secret is returned by exactly the call that minted it and by no\nother (ADR-0034 §2, issue #735): a first create, or the re-mint of a config\nthat had none. An ordinary update carries no secret material at all, and\n\"no secret material\" is the *absence* of the field rather than a null: a\n``webhook_secret: null`` in the body reads as \"this config has no secret\",\nwhich is false and would send an integration looking for the bug in the wrong\nplace."}}}}
```

## The ApiSuccessResponse\_WebhookRequestResponse\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_WebhookRequestResponse_":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"$ref":"#/components/schemas/WebhookRequestResponse"},{"type":"null"}]}},"type":"object","title":"ApiSuccessResponse[WebhookRequestResponse]"},"WebhookRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"request_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Request Id"},"execution_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Count"},"webhook_url":{"type":"string","title":"Webhook Url"},"event_type":{"type":"string","title":"Event Type"},"event_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Name"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"request_payload":{"anyOf":[{},{"type":"null"}],"title":"Request Payload"},"error_details":{"anyOf":[{},{"type":"null"}],"title":"Error Details"}},"type":"object","required":["id","webhook_url","event_type","timestamp"],"title":"WebhookRequestResponse","description":"The commercial delivery-attempt response — the status projection plus the payload.\n\nThe two additions are what makes this a PII-bearing read (see\n``docs/audit/adoption-roster.toml``): an integration token holder gets the\nbody Ospree delivered and the failure detail recorded against it."}}}}
```

## The ApiSuccessResponse\_WebhookSecretRotation\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_WebhookSecretRotation_":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"$ref":"#/components/schemas/WebhookSecretRotation"},{"type":"null"}]}},"type":"object","title":"ApiSuccessResponse[WebhookSecretRotation]"},"WebhookSecretRotation":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"webhook_secret":{"type":"string","title":"Webhook Secret"},"expires":{"type":"string","format":"date-time","title":"Expires"}},"type":"object","required":["id","webhook_secret","expires"],"title":"WebhookSecretRotation","description":"The rotate response — the one and only disclosure of the new secret.\n\nIts own model rather than a reuse of :class:`WebhookConfiguration`, because\nthe two say different things: a configuration *may* carry a secret, a rotation\nalways does. Storing it is the caller's only chance; the value is never\nreturned again by any route, including a repeat of the rotate call (which\nmints a further replacement instead).\n\nThe secret is **pending**, not active: Ospree keeps signing with the current\nsecret until the tenant calls activate, so the two never race. ``expires`` is\nwhen the pending secret stops being promotable."}}}}
```

## The ApiSuccessResponse\_bool\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ApiSuccessResponse_bool_":{"properties":{"status":{"type":"string","title":"Status","default":"success"},"data":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Data"}},"type":"object","title":"ApiSuccessResponse[bool]"}}}}
```

## The ConfigureWebhookRequest object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"ConfigureWebhookRequest":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"event_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Names"},"ip_allowlist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ip Allowlist"},"event_type":{"type":"integer","title":"Event Type"}},"type":"object","required":["webhook_url","event_type"],"title":"ConfigureWebhookRequest","description":"Configure this business's webhook endpoint for one event family. The call is an upsert and carries no endpoint id: it updates the endpoint the family already has, and creates one when it has none. A business may hold up to 5 endpoints per event family, but this route never creates a second one — when the family already holds more than one endpoint it answers 409 rather than guessing which to overwrite. Use GET /webhooks to list them and DELETE /webhooks/{id} to address one by id."}}}}
```

## The Page\_WebhookRequestResponse\_ object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"Page_WebhookRequestResponse_":{"properties":{"items":{"items":{"$ref":"#/components/schemas/WebhookRequestResponse"},"type":"array","title":"Items"},"total":{"type":"integer","minimum":0,"title":"Total"},"page":{"type":"integer","minimum":1,"title":"Page"},"size":{"type":"integer","minimum":1,"title":"Size"},"pages":{"type":"integer","minimum":0,"title":"Pages"}},"type":"object","required":["items","total","page","size","pages"],"title":"Page[WebhookRequestResponse]"},"WebhookRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"request_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Request Id"},"execution_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Count"},"webhook_url":{"type":"string","title":"Webhook Url"},"event_type":{"type":"string","title":"Event Type"},"event_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Name"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"request_payload":{"anyOf":[{},{"type":"null"}],"title":"Request Payload"},"error_details":{"anyOf":[{},{"type":"null"}],"title":"Error Details"}},"type":"object","required":["id","webhook_url","event_type","timestamp"],"title":"WebhookRequestResponse","description":"The commercial delivery-attempt response — the status projection plus the payload.\n\nThe two additions are what makes this a PII-bearing read (see\n``docs/audit/adoption-roster.toml``): an integration token holder gets the\nbody Ospree delivered and the failure detail recorded against it."}}}}
```

## The WebhookConfiguration object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"WebhookConfiguration":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"event_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Names"},"ip_allowlist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ip Allowlist"},"id":{"type":"string","format":"uuid","title":"Id"},"event_type":{"type":"integer","title":"Event Type"},"business_id":{"type":"string","format":"uuid","title":"Business Id"},"created_by":{"type":"string","format":"uuid","title":"Created By"},"created":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created"},"modified_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Modified By"},"last_modified":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Modified"},"webhook_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Secret"}},"type":"object","required":["webhook_url","id","event_type","business_id","created_by"],"title":"WebhookConfiguration","description":"What the upsert hands back — with the signing secret only when it minted one.\n\nThe plaintext secret is returned by exactly the call that minted it and by no\nother (ADR-0034 §2, issue #735): a first create, or the re-mint of a config\nthat had none. An ordinary update carries no secret material at all, and\n\"no secret material\" is the *absence* of the field rather than a null: a\n``webhook_secret: null`` in the body reads as \"this config has no secret\",\nwhich is false and would send an integration looking for the bug in the wrong\nplace."}}}}
```

## The WebhookConfigurationView object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"WebhookConfigurationView":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"event_names":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Event Names"},"ip_allowlist":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Ip Allowlist"},"id":{"type":"string","format":"uuid","title":"Id"},"business_id":{"type":"string","format":"uuid","title":"Business Id"},"event_type":{"type":"string","title":"Event Type"},"modified_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Modified By"},"last_modified":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Modified"},"webhook_desc":{"type":"string","title":"Webhook Desc"}},"type":"object","required":["webhook_url","id","business_id","event_type","webhook_desc"],"title":"WebhookConfigurationView"}}}}
```

## The WebhookEventTypeResponse object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"WebhookEventTypeResponse":{"properties":{"event_type_name":{"type":"string","title":"Event Type Name"},"event_type_id":{"type":"string","title":"Event Type Id"}},"type":"object","required":["event_type_name","event_type_id"],"title":"WebhookEventTypeResponse"}}}}
```

## The WebhookRequestResponse object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"WebhookRequestResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"request_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Request Id"},"execution_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Execution Count"},"webhook_url":{"type":"string","title":"Webhook Url"},"event_type":{"type":"string","title":"Event Type"},"event_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Name"},"status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"request_payload":{"anyOf":[{},{"type":"null"}],"title":"Request Payload"},"error_details":{"anyOf":[{},{"type":"null"}],"title":"Error Details"}},"type":"object","required":["id","webhook_url","event_type","timestamp"],"title":"WebhookRequestResponse","description":"The commercial delivery-attempt response — the status projection plus the payload.\n\nThe two additions are what makes this a PII-bearing read (see\n``docs/audit/adoption-roster.toml``): an integration token holder gets the\nbody Ospree delivered and the failure detail recorded against it."}}}}
```

## The WebhookSecretRotation object

```json
{"openapi":"3.1.0","info":{"title":"Ospree Webhooks API","version":"2.0.0"},"components":{"schemas":{"WebhookSecretRotation":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"webhook_secret":{"type":"string","title":"Webhook Secret"},"expires":{"type":"string","format":"date-time","title":"Expires"}},"type":"object","required":["id","webhook_secret","expires"],"title":"WebhookSecretRotation","description":"The rotate response — the one and only disclosure of the new secret.\n\nIts own model rather than a reuse of :class:`WebhookConfiguration`, because\nthe two say different things: a configuration *may* carry a secret, a rotation\nalways does. Storing it is the caller's only chance; the value is never\nreturned again by any route, including a repeat of the rotate call (which\nmints a further replacement instead).\n\nThe secret is **pending**, not active: Ospree keeps signing with the current\nsecret until the tenant calls activate, so the two never race. ``expires`` is\nwhen the pending secret stops being promotable."}}}}
```
