{
  "openapi": "3.1.0",
  "info": {
    "title": "GraftPro Public API",
    "version": "1.0",
    "description": "Stable v1 contract. Read Compliance Passports and create training requests. Breaking changes ship as v2.\n\nLegacy endpoints `/functions/v1/v1-partner-passport` and `/functions/v1/crm-training-request-inbound` are frozen and now return HTTP 410 Gone. They will be removed on 2026-06-27. Migrate to `GET /v1/passport` and `POST /v1/training-requests` respectively.",
    "contact": {
      "name": "GraftPro",
      "email": "hello@graftpro.io"
    },
    "termsOfService": "https://graftpro.io/legal/terms"
  },
  "servers": [
    {
      "url": "https://bswlvqnealsviiocmiyc.supabase.co/functions/v1/v1",
      "description": "Production"
    }
  ],
  "components": {
    "securitySchemes": {
      "ApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key"
      },
      "Signature": {
        "type": "apiKey",
        "in": "header",
        "name": "x-graftpro-signature"
      },
      "PassportToken": {
        "type": "apiKey",
        "in": "query",
        "name": "token"
      }
    }
  },
  "paths": {
    "/health": {
      "get": {
        "summary": "Liveness probe",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "summary": "This document",
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/passport": {
      "get": {
        "summary": "Read a Compliance Passport by token",
        "security": [
          {
            "PassportToken": []
          }
        ],
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Passport payload"
          },
          "400": {
            "description": "Missing or invalid token"
          },
          "404": {
            "description": "Passport not found"
          },
          "410": {
            "description": "Passport revoked or expired"
          }
        }
      }
    },
    "/passport/{token}": {
      "get": {
        "summary": "Read a Compliance Passport by token (REST style)",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Passport payload"
          },
          "404": {
            "description": "Passport not found"
          },
          "410": {
            "description": "Passport revoked or expired"
          }
        }
      }
    },
    "/training-requests": {
      "post": {
        "summary": "Create a training request on behalf of a customer",
        "security": [
          {
            "ApiKey": [],
            "Signature": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ticket_type"
                ],
                "properties": {
                  "requesting_company_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "requesting_company_name": {
                    "type": "string"
                  },
                  "worker_id": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "worker_full_name": {
                    "type": "string"
                  },
                  "worker_employee_id": {
                    "type": "string"
                  },
                  "worker_email": {
                    "type": "string",
                    "format": "email"
                  },
                  "ticket_type": {
                    "type": "string"
                  },
                  "custom_ticket_name": {
                    "type": "string"
                  },
                  "urgency": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "urgent"
                    ]
                  },
                  "scheduled_date": {
                    "type": "string",
                    "format": "date"
                  },
                  "cost": {
                    "type": "number"
                  },
                  "notes": {
                    "type": "string"
                  },
                  "external_ref": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Training request created"
          },
          "401": {
            "description": "Auth failed"
          },
          "422": {
            "description": "Could not resolve company or worker"
          }
        }
      }
    },
    "/v1-partner-passport": {
      "get": {
        "summary": "DEPRECATED. Legacy passport endpoint.",
        "description": "Frozen on 2026-05-13. Returns HTTP 410 Gone for every request. Removal date: 2026-06-27. Migrate to `GET /v1/passport`.",
        "deprecated": true,
        "servers": [
          {
            "url": "https://bswlvqnealsviiocmiyc.supabase.co/functions/v1",
            "description": "Legacy host"
          }
        ],
        "responses": {
          "410": {
            "description": "Endpoint deprecated. Body: { error, use, removal_date, docs }. Headers include `Sunset` and `Link: rel=\"successor-version\"` pointing at /functions/v1/v1/passport."
          }
        }
      }
    },
    "/crm-training-request-inbound": {
      "post": {
        "summary": "DEPRECATED. Legacy training request inbound.",
        "description": "Frozen on 2026-05-13. Returns HTTP 410 Gone for every request. Removal date: 2026-06-27. Migrate to `POST /v1/training-requests`.",
        "deprecated": true,
        "servers": [
          {
            "url": "https://bswlvqnealsviiocmiyc.supabase.co/functions/v1",
            "description": "Legacy host"
          }
        ],
        "responses": {
          "410": {
            "description": "Endpoint deprecated. Body: { error, use, removal_date, docs }. Headers include `Sunset` and `Link: rel=\"successor-version\"` pointing at /functions/v1/v1/training-requests."
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "GraftPro Developers",
    "url": "https://graftpro.io/developers"
  }
}
