{
  "openapi": "3.1.0",
  "info": {
    "title": "Homing Pigeon",
    "version": "1.0.0",
    "description": "Homing Pigeon (homingpigeon.dev) sends text-message alerts from your code or your coding agent to one phone: yours. No carrier registration, no app, no browser signup. Free to start."
  },
  "servers": [{ "url": "https://homingpigeon.dev" }],
  "components": {
    "securitySchemes": { "apiKey": { "type": "http", "scheme": "bearer" } },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "required": ["code", "message", "next_step"],
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "next_step": { "type": "string", "description": "What to do about this error." }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/verify": {
      "post": {
        "operationId": "verify",
        "summary": "Verify the user's own phone. Send phone alone to text a six-digit code, then phone and code to receive an API key.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["phone"],
                "properties": {
                  "phone": { "type": "string", "description": "The user's own US mobile number." },
                  "code": { "type": "string", "description": "The six-digit code the user received." },
                  "project": { "type": "string", "maxLength": 32, "description": "Name shown in front of each message from this key." }
                }
              }
            }
          }
        },
        "responses": {
          "200": { "description": "Verified. The response contains api_key." },
          "202": { "description": "Code sent. Ask the user for it." },
          "default": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/v1/send": {
      "post": {
        "operationId": "send",
        "summary": "Send a text message to the account owner's verified phone. The recipient is fixed; message is the only required field.",
        "security": [{ "apiKey": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["message"],
                "additionalProperties": false,
                "properties": {
                  "message": { "type": "string", "maxLength": 480 },
                  "idempotency_key": { "type": "string", "maxLength": 128, "description": "Reuse on a retry so it cannot double-text." }
                }
              }
            }
          }
        },
        "responses": {
          "202": { "description": "Accepted. Delivery is reported by GET /v1/status." },
          "default": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    },
    "/v1/status": {
      "get": {
        "operationId": "status",
        "summary": "Report whether the number is verified or paused, how many messages remain, and what happened to the last send.",
        "security": [{ "apiKey": [] }],
        "responses": {
          "200": { "description": "Account state." },
          "default": { "description": "Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  }
}
