{
  "openapi": "3.1.0",
  "info": {
    "title": "catchbin Public API",
    "version": "0.1.0",
    "description": "\n\n**Download the OpenAPI spec:** [YAML](/openapi.yaml) · [JSON](/openapi.json) — import into Postman/Insomnia/Bruno or run codegen."
  },
  "servers": [
    {
      "url": "https://api.catchbin.io",
      "description": "Generated server url"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/endpoints": {
      "get": {
        "tags": [
          "Operations"
        ],
        "summary": "List endpoints",
        "operationId": "list",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointListResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Operations"
        ],
        "summary": "Create endpoint",
        "operationId": "create",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEndpointRequest"
              }
            }
          },
          "required": true
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/endpoints/{endpointId}/events": {
      "get": {
        "tags": [
          "Operations"
        ],
        "summary": "List captured events for an endpoint",
        "operationId": "list_1",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "beforeId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "after",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "afterId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "eventType",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "provider",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "responseCode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/EventListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/endpoints/{endpointId}/events/{eventId}": {
      "get": {
        "tags": [
          "Operations"
        ],
        "summary": "Get one captured event with decrypted body",
        "operationId": "detail",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/EventDetailResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Operations"
        ],
        "summary": "Delete a captured event (idempotent)",
        "operationId": "delete_1",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/endpoints/{endpointId}/events/{eventId}/curl": {
      "get": {
        "tags": [
          "Operations"
        ],
        "summary": "Export a captured event as a single-line bash cURL command",
        "operationId": "exportCurl",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "unmasked",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/CurlExportResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/endpoints/{endpointId}/events/{eventId}/replay": {
      "post": {
        "tags": [
          "Operations"
        ],
        "summary": "Replay a captured event against an alternate target",
        "operationId": "replay",
        "parameters": [
          {
            "name": "endpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "eventId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplayRequestDto"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/ReplayResponseDto"
                }
              }
            }
          },
          "429": {
            "description": "Per-account daily replay limit reached (issue #293). The response carries a Retry-After header (seconds to the next UTC midnight) and RateLimit-Limit / RateLimit-Remaining / RateLimit-Reset headers.",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/ReplayResponseDto"
                }
              }
            }
          }
        }
      }
    },
    "/v1/endpoints/{id}": {
      "get": {
        "tags": [
          "Operations"
        ],
        "summary": "Get endpoint",
        "operationId": "get",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "*/*": {
                "schema": {
                  "$ref": "#/components/schemas/EndpointResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Operations"
        ],
        "summary": "Delete endpoint",
        "operationId": "delete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ReplayRequestDto": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string"
          },
          "target_url": {
            "type": "string",
            "minLength": 1
          },
          "target_secret": {
            "type": "string"
          }
        },
        "required": [
          "target_url"
        ]
      },
      "ReplayResponseDto": {
        "type": "object",
        "properties": {
          "result": {
            "type": "string"
          },
          "target_status": {
            "type": "integer",
            "format": "int32"
          },
          "network_failure_reason": {
            "type": "string"
          },
          "duration_ms": {
            "type": "integer",
            "format": "int64"
          },
          "response_excerpt_base64": {
            "type": "string"
          },
          "excerpt_truncated": {
            "type": "boolean"
          },
          "source_body_truncated": {
            "type": "boolean"
          },
          "mode": {
            "type": "string"
          },
          "target_url": {
            "type": "string"
          },
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "audit_id": {
            "type": "string",
            "format": "uuid"
          }
        }
      },
      "CreateEndpointRequest": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "pattern": "^[a-z0-9][a-z0-9_-]{0,63}$"
          },
          "displayName": {
            "type": "string",
            "maxLength": 100,
            "minLength": 1
          },
          "operatingMode": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "replayFromDashboard": {
            "type": "boolean"
          },
          "replayFromApi": {
            "type": "boolean"
          },
          "genericSignatureHeader": {
            "type": "string"
          },
          "genericSignaturePrefix": {
            "type": "string"
          }
        }
      },
      "EndpointResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "slug": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "webhookUrl": {
            "type": "string"
          },
          "operatingMode": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "replayFromDashboard": {
            "type": "boolean"
          },
          "replayFromApi": {
            "type": "boolean"
          },
          "provider": {
            "type": "string"
          },
          "secretSet": {
            "type": "boolean"
          },
          "genericSignatureHeader": {
            "type": "string"
          },
          "genericSignaturePrefix": {
            "type": "string"
          },
          "source": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "eventCount": {
            "type": "integer",
            "format": "int64"
          },
          "lastEventAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastPurgedAt": {
            "type": "string",
            "format": "date-time"
          },
          "purgedEventCount": {
            "type": "integer",
            "format": "int64"
          }
        }
      },
      "EventDetailResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "endpointId": {
            "type": "string",
            "format": "uuid"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "method": {
            "type": "string"
          },
          "canonicalEventType": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "verification": {
            "type": "string"
          },
          "verificationFailureReason": {
            "type": "string"
          },
          "responseCode": {
            "type": "integer",
            "format": "int32"
          },
          "readAt": {
            "type": "string",
            "format": "date-time"
          },
          "truncated": {
            "type": "boolean"
          },
          "originalSizeBytes": {
            "type": "integer",
            "format": "int64"
          },
          "decryption": {
            "type": "string",
            "enum": [
              "ok",
              "failed",
              "metadata_only"
            ]
          },
          "headers": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "remoteIp": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "bodyEncoding": {
            "type": "string"
          },
          "diagnostic": {
            "type": "object",
            "additionalProperties": {}
          },
          "forwardedResponse": {
            "type": "object",
            "additionalProperties": {}
          }
        }
      },
      "CurlExportResponse": {
        "type": "object",
        "properties": {
          "command": {
            "type": "string"
          },
          "byteIdentical": {
            "type": "boolean"
          },
          "bodyOmitted": {
            "type": "boolean"
          },
          "headersMasked": {
            "type": "boolean"
          }
        }
      },
      "EventListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventSummary"
            }
          },
          "nextBefore": {
            "type": "string",
            "format": "date-time"
          },
          "nextBeforeId": {
            "type": "string",
            "format": "uuid"
          },
          "nextAfter": {
            "type": "string",
            "format": "date-time"
          },
          "nextAfterId": {
            "type": "string",
            "format": "uuid"
          },
          "searchExcludedMetadataOnlyCount": {
            "type": "integer",
            "format": "int32"
          }
        }
      },
      "EventSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "endpointId": {
            "type": "string",
            "format": "uuid"
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "method": {
            "type": "string"
          },
          "canonicalEventType": {
            "type": "string"
          },
          "provider": {
            "type": "string"
          },
          "verification": {
            "type": "string"
          },
          "verificationFailureReason": {
            "type": "string"
          },
          "responseCode": {
            "type": "integer",
            "format": "int32"
          },
          "readAt": {
            "type": "string",
            "format": "date-time"
          },
          "truncated": {
            "type": "boolean"
          },
          "originalSizeBytes": {
            "type": "integer",
            "format": "int64"
          },
          "decryption": {
            "type": "string",
            "enum": [
              "ok",
              "failed",
              "metadata_only"
            ]
          },
          "searchMatchedTruncated": {
            "type": "boolean"
          }
        }
      },
      "EndpointListResponse": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EndpointResponse"
            }
          }
        }
      }
    },
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "description": "Catchbin API key presented as a Bearer token.",
        "scheme": "bearer"
      }
    }
  }
}
