Ctrl K
ComunidadGuías…

openapi.yaml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
openapi: 3.0.3
info:
  title: Raptor API
  description: |
    Self-hosted webhook/email/DNS capture & inspection. This document is the
    spec-first source of truth for the versioned management API under `/api/v1`.
    The SPA is a pure client of it.

    **Authentication.** When `--require-auth` is enabled, send `Api-Key: <uuid>`.
    With no key configured the API is open (first-run bootstrap mode).
  version: "1.0"
servers:
  - url: /api/v1
paths:
  /groups:
    get:
      summary: List groups
      operationId: listGroups
      responses:
        "200":
          description: All groups
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: "#/components/schemas/Group" }
    post:
      summary: Create a group
      operationId: createGroup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name: { type: string }
                color: { type: string }
      responses:
        "201":
          description: Created group
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Group" }
  /groups/{groupID}:
    parameters:
      - { name: groupID, in: path, required: true, schema: { type: string } }
    put:
      summary: Update a group
      operationId: updateGroup
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name: { type: string }
                color: { type: string }
      responses:
        "200":
          description: Updated group
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Group" }
    delete:
      summary: Delete a group (tokens are kept and detached)
      operationId: deleteGroup
      responses:
        "204": { description: Deleted }
        "404": { description: Not found }
  /schedules:
    get:
      summary: List schedules
      operationId: listSchedules
      responses:
        "200":
          description: Schedules
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/Schedule" } }
    post:
      summary: Create a schedule
      operationId: createSchedule
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ScheduleInput" }
      responses:
        "201":
          description: Created schedule
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Schedule" }
  /schedules/{scheduleID}:
    parameters:
      - { name: scheduleID, in: path, required: true, schema: { type: string } }
    get:
      summary: Get a schedule
      operationId: getSchedule
      responses:
        "200":
          description: Schedule
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Schedule" }
    put:
      summary: Update a schedule
      operationId: updateSchedule
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ScheduleInput" }
      responses:
        "200":
          description: Updated schedule
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Schedule" }
    delete:
      summary: Delete a schedule
      operationId: deleteSchedule
      responses:
        "204": { description: Deleted }
  /schedules/{scheduleID}/runs:
    parameters:
      - { name: scheduleID, in: path, required: true, schema: { type: string } }
    get:
      summary: List a schedule's run history
      operationId: listScheduleRuns
      responses:
        "200":
          description: Runs
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/ScheduleRun" } }
  /schedules/{scheduleID}/run:
    parameters:
      - { name: scheduleID, in: path, required: true, schema: { type: string } }
    post:
      summary: Run a schedule immediately
      operationId: runScheduleNow
      responses:
        "200":
          description: Run result
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ScheduleRun" }
  /tokens/{tokenID}/replay:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    post:
      summary: Replay a subset of captured requests to a target URL
      operationId: replayRequests
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [target_url]
              properties:
                target_url: { type: string }
                q: { type: string, description: "search DSL to select the subset" }
                date_from: { type: string }
                date_to: { type: string }
                limit: { type: integer }
      responses:
        "200":
          description: Replay counts
          content:
            application/json:
              schema:
                type: object
                properties:
                  replayed: { type: integer }
                  failed: { type: integer }
  /auth/status:
    get:
      summary: Auth/bootstrap status and current user
      operationId: authStatus
      responses:
        "200":
          description: Status
          content:
            application/json:
              schema:
                type: object
                properties:
                  bootstrapped: { type: boolean }
                  require_auth: { type: boolean }
                  allow_registration: { type: boolean }
                  authenticated: { type: boolean }
                  user: { $ref: "#/components/schemas/User" }
  /auth/register:
    post:
      summary: Register an account (first one becomes admin; adopts anonymous URLs)
      operationId: register
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/Credentials" }
      responses:
        "201": { description: Account created and signed in }
        "403": { description: Registration disabled }
  /auth/bootstrap:
    post:
      summary: Create the first admin (only when no users exist)
      operationId: bootstrap
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/Credentials" }
      responses:
        "201": { description: Admin created and signed in }
        "409": { description: Already initialised }
  /auth/login:
    post:
      summary: Sign in (sets a session cookie)
      operationId: login
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/Credentials" }
      responses:
        "200": { description: Signed in }
        "401": { description: Invalid credentials }
  /auth/logout:
    post:
      summary: Sign out
      operationId: logout
      responses:
        "204": { description: Signed out }
  /auth/me:
    get:
      summary: Current authenticated user
      operationId: me
      responses:
        "200":
          description: User
          content:
            application/json:
              schema: { $ref: "#/components/schemas/User" }
        "401": { description: Not authenticated }
  /account/api-keys:
    get:
      summary: List the current user's API keys
      operationId: listAPIKeys
      responses:
        "200":
          description: API keys
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/APIKey" } }
    post:
      summary: Create an API key (plaintext returned once)
      operationId: createAPIKey
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties: { name: { type: string } }
      responses:
        "201":
          description: Created key (the `key` field is shown only here)
          content:
            application/json:
              schema:
                type: object
                properties:
                  key: { type: string }
                  api_key: { $ref: "#/components/schemas/APIKey" }
  /account/api-keys/{keyID}:
    parameters:
      - { name: keyID, in: path, required: true, schema: { type: string } }
    delete:
      summary: Revoke an API key
      operationId: deleteAPIKey
      responses:
        "204": { description: Revoked }
  /users:
    get:
      summary: List users (admin)
      operationId: listUsers
      responses:
        "200":
          description: Users
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/User" } }
        "403": { description: Admin role required }
    post:
      summary: Create a user (admin)
      operationId: createUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email: { type: string }
                password: { type: string }
                role: { type: string, enum: [admin, user] }
      responses:
        "201":
          description: Created user
          content:
            application/json:
              schema: { $ref: "#/components/schemas/User" }
  /users/{userID}:
    parameters:
      - { name: userID, in: path, required: true, schema: { type: string } }
    put:
      summary: Update a user (admin)
      operationId: updateUser
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email: { type: string }
                password: { type: string }
                role: { type: string, enum: [admin, user] }
      responses:
        "200":
          description: Updated user
          content:
            application/json:
              schema: { $ref: "#/components/schemas/User" }
    delete:
      summary: Delete a user (admin)
      operationId: deleteUser
      responses:
        "204": { description: Deleted }
  /action-types:
    get:
      summary: List available Custom Action type names
      operationId: listActionTypes
      responses:
        "200":
          description: Action type names
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { type: string } }
  /tokens/{tokenID}/actions:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: List a token's Custom Actions (in execution order)
      operationId: listActions
      responses:
        "200":
          description: Actions
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/Action" } }
    post:
      summary: Add a Custom Action
      operationId: createAction
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ActionInput" }
      responses:
        "201":
          description: Created action
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Action" }
  /tokens/{tokenID}/actions/{actionID}:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - { name: actionID, in: path, required: true, schema: { type: string } }
    put:
      summary: Update a Custom Action
      operationId: updateAction
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ActionInput" }
      responses:
        "200":
          description: Updated action
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Action" }
    delete:
      summary: Delete a Custom Action
      operationId: deleteAction
      responses:
        "204": { description: Deleted }
  /tokens/{tokenID}/test-action:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    post:
      summary: Test a single action definition against the latest request
      operationId: testAction
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ActionInput" }
      responses:
        "200":
          description: Test result (output, error, variables, response)
          content:
            application/json:
              schema: { type: object }
  /tokens/{tokenID}/requests/{requestID}/action-runs:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
    get:
      summary: List the action run log for a request
      operationId: listActionRuns
      responses:
        "200":
          description: Action runs
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/ActionRun" } }
  /tokens/{tokenID}/requests/{requestID}/response:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
    post:
      summary: Supply the response for a pending request (CLI listen flow)
      operationId: setResponse
      description: >
        When the token has `listen > 0`, a capture is held open until this
        endpoint supplies a response. Body may be base64 (`content`) or raw
        (`content_text`).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                status: { type: integer }
                content: { type: string, description: "base64-encoded body" }
                content_text: { type: string, description: "raw body (alternative to content)" }
                headers: { type: object, additionalProperties: { type: string } }
      responses:
        "204": { description: Response delivered }
        "404": { description: No request is waiting (not listening / already responded) }
  /tokens/{tokenID}/requests/{requestID}/execute:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
    post:
      summary: Replay the action chain against a stored request
      operationId: executeChain
      responses:
        "200":
          description: Resulting action runs
          content:
            application/json:
              schema:
                type: object
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/ActionRun" } }
  /tokens:
    get:
      summary: List tokens
      operationId: listTokens
      responses:
        "200":
          description: All tokens
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: "#/components/schemas/Token" }
    post:
      summary: Create a token
      operationId: createToken
      requestBody:
        required: false
        content:
          application/json:
            schema: { $ref: "#/components/schemas/TokenInput" }
      responses:
        "201":
          description: Created token
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Token" }
        "409": { description: Alias already in use }
  /tokens/{tokenID}:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: Get a token
      operationId: getToken
      responses:
        "200":
          description: Token
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Token" }
        "404": { description: Not found }
    put:
      summary: Update a token
      operationId: updateToken
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/TokenInput" }
      responses:
        "200":
          description: Updated token
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Token" }
    delete:
      summary: Delete a token and all its data
      operationId: deleteToken
      responses:
        "204": { description: Deleted }
        "404": { description: Not found }
  /tokens/{tokenID}/stream:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: Stream newly captured requests (Server-Sent Events)
      operationId: streamRequests
      description: |
        Opens a long-lived `text/event-stream`. Each captured request is sent as
        an `event: request` with the JSON request object as `data`. Comment lines
        (`: ping`) are heartbeats.
      responses:
        "200":
          description: SSE stream
          content:
            text/event-stream:
              schema: { type: string }
  /tokens/{tokenID}/requests:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: List captured requests (paged, newest first)
      operationId: listRequests
      parameters:
        - { name: page, in: query, schema: { type: integer, default: 1 } }
        - { name: per_page, in: query, schema: { type: integer, default: 50, maximum: 100 } }
        - name: q
          in: query
          description: >
            Search DSL. Free text matches content; field filters include
            `content:`, `method:`, `type:`, `ip:`, `host:`, `url:`, `query:`,
            `headers.<key>:`, `_exists_:<field>`, and
            `created_at:[* TO now-14d]`. Terms are ANDed; quote values with spaces.
          schema: { type: string }
        - { name: date_from, in: query, description: "ISO date/datetime lower bound", schema: { type: string } }
        - { name: date_to, in: query, description: "ISO date/datetime upper bound", schema: { type: string } }
      responses:
        "200":
          description: Page of requests
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items: { $ref: "#/components/schemas/Request" }
                  total: { type: integer }
                  page: { type: integer }
                  per_page: { type: integer }
    delete:
      summary: Delete requests for the token (all, or a `q`/`date_from`/`date_to` subset)
      operationId: deleteAllRequests
      parameters:
        - { name: q, in: query, description: "search DSL; deletes only matching requests", schema: { type: string } }
        - { name: date_from, in: query, schema: { type: string } }
        - { name: date_to, in: query, schema: { type: string } }
      responses:
        "200":
          description: Number deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  deleted: { type: integer }
  /tokens/{tokenID}/requests.csv:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: Export all captured requests as CSV
      operationId: exportCSV
      responses:
        "200":
          description: CSV download
          content:
            text/csv:
              schema: { type: string }
  /tokens/{tokenID}/requests/latest:
    parameters:
      - $ref: "#/components/parameters/TokenID"
    get:
      summary: Get the most recent request
      operationId: latestRequest
      responses:
        "200":
          description: Request
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Request" }
        "404": { description: No requests yet }
  /tokens/{tokenID}/requests/{requestID}:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
    get:
      summary: Get a single request
      operationId: getRequest
      responses:
        "200":
          description: Request
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Request" }
        "404": { description: Not found }
    delete:
      summary: Delete a single request
      operationId: deleteRequest
      responses:
        "204": { description: Deleted }
        "404": { description: Not found }
  /tokens/{tokenID}/requests/{requestID}/raw:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
    get:
      summary: Get the raw HTTP representation of a request
      operationId: rawRequest
      responses:
        "200":
          description: Raw request
          content:
            text/plain:
              schema: { type: string }
  /tokens/{tokenID}/requests/{requestID}/files/{fileID}:
    parameters:
      - $ref: "#/components/parameters/TokenID"
      - $ref: "#/components/parameters/RequestID"
      - { name: fileID, in: path, required: true, schema: { type: string } }
    get:
      summary: Download a request's attached file
      operationId: downloadFile
      responses:
        "200":
          description: File blob
          content:
            application/octet-stream:
              schema: { type: string, format: binary }
        "404": { description: Not found }
components:
  parameters:
    TokenID:
      name: tokenID
      in: path
      required: true
      description: Token UUID or alias
      schema: { type: string }
    RequestID:
      name: requestID
      in: path
      required: true
      schema: { type: string }
  schemas:
    TokenInput:
      type: object
      properties:
        alias: { type: string }
        default_status: { type: integer, default: 200 }
        default_content: { type: string }
        default_content_type: { type: string, default: text/plain }
        timeout: { type: integer, description: "drives the 100/timeout rpm rate limit; 0 = unlimited" }
        cors: { type: boolean }
        expiry: { type: integer, description: "TTL seconds from creation; 0 = never" }
        actions: { type: boolean }
        request_limit: { type: integer, description: "max stored requests; 0 = unlimited" }
        description: { type: string }
        listen: { type: integer }
        redirect: { type: string }
        group_id: { type: string }
        clone_from: { type: string, description: "copy settings from an existing token UUID" }
    Token:
      type: object
      properties:
        uuid: { type: string }
        alias: { type: string }
        url: { type: string, description: "copyable capture URL" }
        default_status: { type: integer }
        default_content: { type: string }
        default_content_type: { type: string }
        timeout: { type: integer }
        cors: { type: boolean }
        expiry: { type: integer }
        actions: { type: boolean }
        request_limit: { type: integer }
        description: { type: string }
        listen: { type: integer }
        redirect: { type: string }
        group_id: { type: string }
        premium: { type: boolean }
        has_password: { type: boolean }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
        latest_request_at: { type: string, format: date-time, nullable: true }
    Request:
      type: object
      properties:
        uuid: { type: string }
        token_id: { type: string }
        type: { type: string, enum: [web, email, dns] }
        method: { type: string }
        ip: { type: string }
        hostname: { type: string }
        user_agent: { type: string }
        content: { type: string }
        query: { type: object, additionalProperties: { type: array, items: { type: string } } }
        headers: { type: object, additionalProperties: { type: array, items: { type: string } } }
        url: { type: string }
        size: { type: integer }
        sorting: { type: integer, format: int64 }
        files:
          type: array
          items: { $ref: "#/components/schemas/File" }
        created_at: { type: string, format: date-time }
        # Email-specific fields (type == email)
        sender: { type: string }
        message_id: { type: string }
        destinations: { type: string }
        subject: { type: string }
        text_content: { type: string }
        checks:
          type: object
          description: "DKIM/SPF/DMARC results, e.g. {\"dkim\":\"pass\",\"spf\":\"fail\"}"
          additionalProperties: { type: string }
    File:
      type: object
      properties:
        id: { type: string }
        request_id: { type: string }
        filename: { type: string }
        content_type: { type: string }
        size: { type: integer }
    Group:
      type: object
      properties:
        id: { type: string }
        name: { type: string }
        color: { type: string }
        created_at: { type: string, format: date-time }
    ActionInput:
      type: object
      required: [type]
      properties:
        type:
          type: string
          description: "set_variable | modify_response | conditions | extract_json | extract_regex | http_request | script | dont_save | stop"
        name: { type: string }
        position: { type: integer }
        disabled: { type: boolean }
        parameters: { type: object, description: "type-specific parameters" }
    Action:
      allOf:
        - $ref: "#/components/schemas/ActionInput"
        - type: object
          properties:
            uuid: { type: string }
            token_id: { type: string }
            created_at: { type: string, format: date-time }
            updated_at: { type: string, format: date-time }
    ActionRun:
      type: object
      properties:
        id: { type: string }
        request_id: { type: string }
        action_id: { type: string }
        action_type: { type: string }
        action_name: { type: string }
        position: { type: integer }
        output: { type: string }
        error: { type: string }
        created_at: { type: string, format: date-time }
    ScheduleInput:
      type: object
      required: [cron]
      properties:
        token_id: { type: string }
        name: { type: string }
        cron: { type: string, description: "5-field cron expression" }
        target_url: { type: string }
        method: { type: string }
        body: { type: string }
        run_actions: { type: boolean, description: "run the token's action chain instead of an HTTP check" }
        expect_status: { type: integer, description: "0 = any 2xx is OK" }
        keyword: { type: string, description: "alert if the response body lacks this" }
        check_ssl: { type: boolean }
        ssl_days: { type: integer }
        notify_url: { type: string, description: "Shoutrrr alert URL; write-only, never returned" }
        enabled: { type: boolean }
    Schedule:
      type: object
      properties:
        uuid: { type: string }
        token_id: { type: string }
        name: { type: string }
        cron: { type: string }
        target_url: { type: string }
        method: { type: string }
        body: { type: string }
        run_actions: { type: boolean }
        expect_status: { type: integer }
        keyword: { type: string }
        check_ssl: { type: boolean }
        ssl_days: { type: integer }
        has_notify: { type: boolean, description: "whether an alert URL is configured (masked)" }
        enabled: { type: boolean }
        last_run: { type: string, format: date-time, nullable: true }
        next_run: { type: string, format: date-time, nullable: true }
        last_status: { type: string, enum: [ok, alert, error] }
        last_message: { type: string }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
    ScheduleRun:
      type: object
      properties:
        id: { type: string }
        schedule_id: { type: string }
        status: { type: string, enum: [ok, alert, error] }
        status_code: { type: integer }
        message: { type: string }
        duration_ms: { type: integer }
        created_at: { type: string, format: date-time }
    Credentials:
      type: object
      required: [email, password]
      properties:
        email: { type: string }
        password: { type: string }
    User:
      type: object
      properties:
        id: { type: string }
        email: { type: string }
        role: { type: string, enum: [admin, user] }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
    APIKey:
      type: object
      properties:
        id: { type: string }
        user_id: { type: string }
        name: { type: string }
        last_used_at: { type: string, format: date-time, nullable: true }
        created_at: { type: string, format: date-time }
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: Api-Key