Skip to content
All pages

Reference

Integrations

Signed webhooks and chat destinations, registered over the API, so nothing has to poll.

Register a destination

POST /api/v1/integrations

Register a destination. The signing secret is returned once, here.

integrations:write

Body

name string required

What the destination is called in the delivery ledger.

channel string required

Where posts go: webhook (signed JSON to your endpoint), slack or discord (an incoming webhook URL of theirs).

url string required

The address to post to. Never read back; responses show a redacted hint instead.

events array required

What to post, from GET /api/v1/integrations/events. At least one.

active boolean

Whether the destination is switched on. Defaults to true.

Answers

201

Created. The signing secret is in this response and nowhere else.

409

The destination cap is reached. No tier lifts it; remove one to add another.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

POST /api/v1/integrations
curl -X POST https://titanweather.com/api/v1/integrations \
  -H "Authorization: Bearer $TITAN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Claims system",
    "channel": "webhook",
    "url": "https://claims.example.com/hooks/titan-weather",
    "events": [
        "exposure.detected",
        "warning.issued",
        "report.completed",
        "report.pdf_ready"
    ]
}'
Response 201
{
    "data": {
        "id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
        "object": "integration",
        "name": "Claims system",
        "channel": "webhook",
        "channel_label": "Webhook",
        "address_hint": "https://claims.example.com/...weather",
        "events": [
            "exposure.detected",
            "warning.issued",
            "report.completed",
            "report.pdf_ready"
        ],
        "active": true,
        "signed": true,
        "last_sent_at": "2026-08-23T13:51:02Z",
        "last_failed_at": null,
        "last_failure": null,
        "created_at": "2026-07-14T10:00:00Z",
        "updated_at": "2026-08-23T13:51:02Z",
        "links": {
            "self": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
            "deliveries": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries"
        }
    },
    "secret": "whsec_6b0a4f1d92e8735a6c410b9f2d8e07c5"
}

List destinations

GET /api/v1/integrations

Where the team's systems are told what happened.

integrations:read paginated

Query parameters

channel enum

Only destinations on this channel.

event string

Only destinations subscribed to this event.

active boolean

Only destinations that are (or are not) switched on.

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations
curl https://titanweather.com/api/v1/integrations \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "data": [
        {
            "id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
            "object": "integration",
            "name": "Claims system",
            "channel": "webhook",
            "channel_label": "Webhook",
            "address_hint": "https://claims.example.com/...weather",
            "events": [
                "exposure.detected",
                "warning.issued",
                "report.completed",
                "report.pdf_ready"
            ],
            "active": true,
            "signed": true,
            "last_sent_at": "2026-08-23T13:51:02Z",
            "last_failed_at": null,
            "last_failure": null,
            "created_at": "2026-07-14T10:00:00Z",
            "updated_at": "2026-08-23T13:51:02Z",
            "links": {
                "self": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
                "deliveries": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries"
            }
        }
    ],
    "links": {
        "first": "https://titanweather.com/api/v1/integrations?page=1",
        "last": "https://titanweather.com/api/v1/integrations?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://titanweather.com/api/v1/integrations",
        "per_page": 25,
        "to": 1,
        "total": 1
    }
}

Retrieve a destination

GET /api/v1/integrations/{integration}

One destination.

integrations:read

Path parameters

integration

The destination id, a uuid from a register or list response.

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations/{integration}
curl https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7 \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "data": {
        "id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
        "object": "integration",
        "name": "Claims system",
        "channel": "webhook",
        "channel_label": "Webhook",
        "address_hint": "https://claims.example.com/...weather",
        "events": [
            "exposure.detected",
            "warning.issued",
            "report.completed",
            "report.pdf_ready"
        ],
        "active": true,
        "signed": true,
        "last_sent_at": "2026-08-23T13:51:02Z",
        "last_failed_at": null,
        "last_failure": null,
        "created_at": "2026-07-14T10:00:00Z",
        "updated_at": "2026-08-23T13:51:02Z",
        "links": {
            "self": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
            "deliveries": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries"
        }
    }
}

Update a destination

PATCH /api/v1/integrations/{integration}

Change a destination. An absent url keeps the saved one.

integrations:write

Path parameters

integration

The destination id, a uuid from a register or list response.

Body

name string

What the destination is called in the delivery ledger.

channel string

Where posts go: webhook (signed JSON to your endpoint), slack or discord (an incoming webhook URL of theirs).

url string

The address to post to. Never read back; responses show a redacted hint instead.

events array

What to post, from GET /api/v1/integrations/events. At least one.

active boolean

Whether the destination is switched on. Defaults to true.

Answers

200

The answer.

409

The channel was changed without a new address for it to post to.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

PATCH /api/v1/integrations/{integration}
curl -X PATCH https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7 \
  -H "Authorization: Bearer $TITAN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
        "exposure.detected",
        "exposure.escalated",
        "warning.issued",
        "report.completed"
    ]
}'
Response 200
{
    "data": {
        "id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
        "object": "integration",
        "name": "Claims system",
        "channel": "webhook",
        "channel_label": "Webhook",
        "address_hint": "https://claims.example.com/...weather",
        "events": [
            "exposure.detected",
            "warning.issued",
            "report.completed",
            "report.pdf_ready"
        ],
        "active": true,
        "signed": true,
        "last_sent_at": "2026-08-23T13:51:02Z",
        "last_failed_at": null,
        "last_failure": null,
        "created_at": "2026-07-14T10:00:00Z",
        "updated_at": "2026-08-23T13:51:02Z",
        "links": {
            "self": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
            "deliveries": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries"
        }
    }
}

List the event catalogue

GET /api/v1/integrations/events

Everything a destination can subscribe to.

integrations:read

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations/events
curl https://titanweather.com/api/v1/integrations/events \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "object": "list",
    "data": [
        {
            "object": "integration_event",
            "name": "exposure.detected",
            "label": "Storm day detected",
            "description": "A storm day entered the record at something the team watches.",
            "group": "Monitoring"
        },
        {
            "object": "integration_event",
            "name": "report.completed",
            "label": "Report completed",
            "description": "A requested report finished generating. The PDF follows separately.",
            "group": "Reports"
        },
        {
            "object": "integration_event",
            "name": "report.pdf_ready",
            "label": "Report PDF ready",
            "description": "The report's PDF is rendered and stored; the download links are good.",
            "group": "Reports"
        }
    ]
}

Send a test post

POST /api/v1/integrations/{integration}/test

Post a sample now, and say what the receiver answered.

integrations:write

Path parameters

integration

The destination id, a uuid from a register or list response.

Answers

200

The receiver accepted the sample.

502

The receiver refused or failed. detail says what it answered.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

POST /api/v1/integrations/{integration}/test
curl -X POST https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/test \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "object": "integration_test",
    "integration_id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
    "delivered": true,
    "detail": "The receiver answered 200 in 184 ms."
}

Retrieve the signing secret

GET /api/v1/integrations/{integration}/secret

The signing secret, and how to verify a post with it.

integrations:write

Path parameters

integration

The destination id, a uuid from a register or list response.

Answers

200

The answer.

409

This channel authenticates by its address; there is no signature to verify.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations/{integration}/secret
curl https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/secret \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "object": "signing_secret",
    "integration_id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
    "secret": "whsec_6b0a4f1d92e8735a6c410b9f2d8e07c5",
    "header": "X-Titan-Signature",
    "algorithm": "HMAC-SHA256 over \"{timestamp}.{raw body}\", as t=<unix>,v1=<hex>",
    "tolerance_seconds": 300
}

Rotate the signing secret

POST /api/v1/integrations/{integration}/secret

Issue a new signing secret. The old one stops verifying at once.

integrations:write

Path parameters

integration

The destination id, a uuid from a register or list response.

Answers

200

The answer.

409

This channel authenticates by its address; there is no secret to rotate.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

POST /api/v1/integrations/{integration}/secret
curl -X POST https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/secret \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "object": "signing_secret",
    "integration_id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7",
    "secret": "whsec_0d9e73258c6b0a4f1d92e8735a6c410b",
    "header": "X-Titan-Signature",
    "notice": "The previous secret stopped verifying immediately. Update the receiver before the next post."
}

List deliveries to a destination

GET /api/v1/integrations/{integration}/deliveries

What has been posted to this destination, and whether it arrived.

integrations:read paginated

Path parameters

integration

The destination id, a uuid from a register or list response.

Query parameters

status enum

Only deliveries that ended this way.

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations/{integration}/deliveries
curl https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "data": [
        {
            "id": "0198e1a7-8f42-7d63-90b5-1c8f6e3a2d94",
            "object": "delivery",
            "kind": "event",
            "channel": "webhook",
            "status": "sent",
            "status_label": "Sent",
            "subject": "Storm day detected at Cedar Ridge",
            "address_hint": "https://claims.example.com/...weather",
            "attempts": 1,
            "response_code": 200,
            "failure_reason": null,
            "exposure_ids": [
                48213
            ],
            "sent_at": "2026-08-23T13:51:02Z",
            "failed_at": null,
            "created_at": "2026-08-23T13:51:01Z",
            "integration_id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7"
        }
    ],
    "links": {
        "first": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries?page=1",
        "last": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7/deliveries",
        "per_page": 25,
        "to": 1,
        "total": 1
    }
}

List all deliveries

GET /api/v1/integrations/deliveries

What has been posted to any destination, and whether it arrived.

integrations:read paginated

Query parameters

status enum

Only deliveries that ended this way.

Answers

200

The answer.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

GET /api/v1/integrations/deliveries
curl https://titanweather.com/api/v1/integrations/deliveries?status=failed \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 200
{
    "data": [
        {
            "id": "0198e1a7-8f42-7d63-90b5-1c8f6e3a2d94",
            "object": "delivery",
            "kind": "event",
            "channel": "webhook",
            "status": "failed",
            "status_label": "Failed",
            "subject": "Storm day detected at Cedar Ridge",
            "address_hint": "https://claims.example.com/...weather",
            "attempts": 1,
            "response_code": 500,
            "failure_reason": "The receiver answered 500.",
            "exposure_ids": [
                48213
            ],
            "sent_at": null,
            "failed_at": "2026-08-23T13:51:02Z",
            "created_at": "2026-08-23T13:51:01Z",
            "integration_id": "0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7"
        }
    ],
    "links": {
        "first": "https://titanweather.com/api/v1/integrations/deliveries?page=1",
        "last": "https://titanweather.com/api/v1/integrations/deliveries?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "path": "https://titanweather.com/api/v1/integrations/deliveries",
        "per_page": 25,
        "to": 1,
        "total": 1
    }
}

Delete a destination

DELETE /api/v1/integrations/{integration}

Remove a destination. Nothing more is posted there.

integrations:write

Path parameters

integration

The destination id, a uuid from a register or list response.

Answers

204

Deleted. Nothing more is posted there.

Plus the shared refusals: 401, 402, 403, 404, 422 and 429, described on Errors.

DELETE /api/v1/integrations/{integration}
curl -X DELETE https://titanweather.com/api/v1/integrations/0198d4e6-2c58-7a19-8f03-7b9e5d21a4c7 \
  -H "Authorization: Bearer $TITAN_API_TOKEN"
Response 204

No body. Nothing more is posted there; the delivery ledger keeps what already happened.

esc
move open 72 places