{
  "openapi": "3.1.0",
  "info": {
    "title": "Herald Labs Public API",
    "version": "1.0.0",
    "description": "Public API surface for heraldlab.si, the site of The Herald Labs, an AI lab and product company. Version 1 is canonical at /api/v1. Unversioned /api routes are compatibility aliases. The apply endpoint backs the form at https://heraldlab.si/work-with-us. See https://heraldlab.si/developers#versioning-policy for versioning, deprecation, Sunset, and migration policy.",
    "x-api-version": "1",
    "x-versioning-policy": {
      "currentVersion": "v1",
      "strategy": "URL path versioning. Canonical public API paths use /api/v1/... . Unversioned /api/... paths are compatibility aliases for v1 until a future deprecation notice is published.",
      "deprecationSignals": [
        "Deprecation header",
        "Sunset header",
        "Link header with rel=\"deprecation\""
      ],
      "policyUrl": "https://heraldlab.si/developers#versioning-policy",
      "minimumNotice": "90 days for public endpoint removals unless security, abuse, or legal requirements force faster action."
    }
  },
  "servers": [
    {
      "url": "https://heraldlab.si",
      "description": "Production"
    },
    {
      "url": "https://heraldlab.si/api/v1",
      "description": "Canonical v1 API base path"
    }
  ],
  "paths": {
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiSpec",
        "summary": "Fetch the OpenAPI specification",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "OpenAPI 3.1 document for Herald Labs public API.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/llms.txt": {
      "get": {
        "operationId": "getLlmsTxt",
        "summary": "Fetch agent instructions",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "Plain-text agent orientation and when-to-use guidance.",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/api/apply": {
      "post": {
        "operationId": "submitProgramApplicationCompatibilityAlias",
        "summary": "Submit an application or inquiry (v1 compatibility alias)",
        "description": "Compatibility alias for POST /api/v1/apply. Agents should prefer the canonical versioned path /api/v1/apply.",
        "tags": [
          "Applications"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Application accepted or honeypot submission safely ignored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            },
            "headers": {
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Link": {
                "$ref": "#/components/headers/Link"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "500": {
            "$ref": "#/components/responses/DeliveryNotConfigured"
          },
          "502": {
            "$ref": "#/components/responses/DeliveryProviderError"
          }
        },
        "x-api-version": "1",
        "x-compatibility-alias-for": "/api/v1/apply",
        "x-deprecation-policy": "Active endpoints return Deprecation: false. Deprecated endpoints will return Deprecation: true and a Sunset HTTP-date header, with at least 90 days public notice unless security, abuse, or legal requirements force faster action. See https://heraldlab.si/developers#versioning-policy."
      }
    },
    "/api/v1/apply": {
      "post": {
        "operationId": "submitProgramApplicationV1",
        "summary": "Submit an application or inquiry",
        "description": "Canonical v1 endpoint behind the work-with-us form (https://heraldlab.si/work-with-us#apply): join the team, bring a problem, research or media partnerships, and other inquiries. Use only when the user explicitly wants to contact or apply to Herald Labs.",
        "tags": [
          "Applications"
        ],
        "x-api-version": "1",
        "x-versioned-path": "/api/v1/apply",
        "x-deprecation-policy": "Active endpoints return Deprecation: false. Deprecated endpoints will return Deprecation: true and a Sunset HTTP-date header, with at least 90 days public notice unless security, abuse, or legal requirements force faster action. See https://heraldlab.si/developers#versioning-policy.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApplyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Application accepted or honeypot submission safely ignored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            },
            "headers": {
              "API-Version": {
                "$ref": "#/components/headers/ApiVersion"
              },
              "X-API-Version": {
                "$ref": "#/components/headers/XApiVersion"
              },
              "Deprecation": {
                "$ref": "#/components/headers/Deprecation"
              },
              "Link": {
                "$ref": "#/components/headers/Link"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationError"
          },
          "405": {
            "$ref": "#/components/responses/MethodNotAllowed"
          },
          "500": {
            "$ref": "#/components/responses/DeliveryNotConfigured"
          },
          "502": {
            "$ref": "#/components/responses/DeliveryProviderError"
          }
        }
      }
    },
    "/hub.json": {
      "get": {
        "operationId": "getHubFeed",
        "summary": "Latest Herald Labs items as JSON Feed",
        "description": "Episodes, ops logs and digests from across Herald Labs, newest first, each linking to its source. Cached for up to 15 minutes. Items are filtered before publication; when a source is unavailable its last known items are served and _herald.mode is degraded.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "JSON Feed 1.1 document.",
            "content": {
              "application/feed+json": {
                "schema": {
                  "$ref": "#/components/schemas/HubFeed"
                }
              }
            }
          },
          "503": {
            "description": "The hub feed is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/feed.xml": {
      "get": {
        "operationId": "getHubRss",
        "summary": "Latest Herald Labs items as RSS",
        "description": "RSS 2.0 version of /hub.json.",
        "tags": [
          "Discovery"
        ],
        "responses": {
          "200": {
            "description": "RSS 2.0 document.",
            "content": {
              "application/rss+xml": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "503": {
            "description": "The hub feed is temporarily unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Herald Labs developer portal and versioning policy",
    "url": "https://heraldlab.si/developers#versioning-policy"
  },
  "tags": [
    {
      "name": "Applications",
      "description": "Application and project inquiry submission endpoints"
    },
    {
      "name": "Discovery",
      "description": "Machine-readable resources for agents and developers"
    }
  ],
  "components": {
    "schemas": {
      "ApplyRequest": {
        "type": "object",
        "required": [
          "name",
          "email",
          "location",
          "track",
          "idea"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "example": "Ada Example"
          },
          "email": {
            "type": "string",
            "format": "email",
            "example": "ada@example.com"
          },
          "location": {
            "type": "string",
            "minLength": 1,
            "example": "London, United Kingdom"
          },
          "track": {
            "type": "string",
            "minLength": 1,
            "example": "Bring us a problem",
            "description": "Free-form. The website form sends one of: Join the team (MTS), Bring us a problem, Research or partnership, Media: Weekly Claw or Human Upside, Something else."
          },
          "idea": {
            "type": "string",
            "minLength": 1,
            "example": "Agents draft our support replies but nobody reviews them. We want a human review step and a way to prove reply quality improved.",
            "description": "What the person wants to build or solve, and what would prove it works."
          },
          "link": {
            "type": "string",
            "format": "uri",
            "description": "Optional portfolio, GitHub, demo, or project URL",
            "example": "https://example.com/project"
          },
          "_honey": {
            "type": "string",
            "description": "Optional honeypot field; leave empty."
          }
        },
        "additionalProperties": true
      },
      "SuccessResponse": {
        "type": "object",
        "required": [
          "success"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": true,
            "example": true
          }
        }
      },
      "ErrorDetail": {
        "type": "object",
        "required": [
          "code",
          "message",
          "hint"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Stable machine-readable error code",
            "examples": [
              "VALIDATION_ERROR",
              "METHOD_NOT_ALLOWED",
              "FORM_DELIVERY_NOT_CONFIGURED"
            ]
          },
          "message": {
            "type": "string",
            "description": "Human-readable summary of what failed"
          },
          "hint": {
            "type": "string",
            "description": "Actionable recovery guidance for humans and agents"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": [
          "success",
          "error"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "const": false,
            "example": false
          },
          "error": {
            "$ref": "#/components/schemas/ErrorDetail"
          }
        }
      },
      "HubFeedItem": {
        "type": "object",
        "required": [
          "id",
          "url",
          "title",
          "date_published"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "image": {
            "type": "string",
            "format": "uri"
          },
          "date_published": {
            "type": "string",
            "format": "date-time"
          },
          "authors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "_herald": {
            "type": "object",
            "properties": {
              "source": {
                "type": "string",
                "examples": [
                  "Weekly Claw",
                  "SuperAda"
                ]
              },
              "type": {
                "type": "string",
                "examples": [
                  "Episode",
                  "Ops log",
                  "Weekly digest"
                ]
              },
              "week": {
                "type": "string",
                "examples": [
                  "W31"
                ]
              },
              "receipts": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "label": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "HubFeed": {
        "type": "object",
        "required": [
          "version",
          "title",
          "items"
        ],
        "properties": {
          "version": {
            "type": "string",
            "const": "https://jsonfeed.org/version/1.1"
          },
          "title": {
            "type": "string"
          },
          "home_page_url": {
            "type": "string"
          },
          "feed_url": {
            "type": "string"
          },
          "_herald": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "live",
                  "degraded",
                  "snapshot"
                ]
              },
              "generatedAt": {
                "type": "string",
                "format": "date-time"
              },
              "sources": {
                "type": "object",
                "additionalProperties": {
                  "type": "string"
                }
              }
            }
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HubFeedItem"
            }
          }
        }
      }
    },
    "responses": {
      "ValidationError": {
        "description": "The request body is missing required fields or has an invalid email address.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "VALIDATION_ERROR",
                "message": "Complete all required fields with a valid email address.",
                "hint": "Send name, email, location, track, and idea. Email must be a valid address."
              }
            }
          }
        },
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Link": {
            "$ref": "#/components/headers/Link"
          }
        }
      },
      "MethodNotAllowed": {
        "description": "The endpoint only accepts POST requests.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "METHOD_NOT_ALLOWED",
                "message": "Method not allowed.",
                "hint": "Send a POST request to https://heraldlab.si/api/v1/apply. The unversioned /api/apply route remains a compatibility alias."
              }
            }
          }
        },
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Link": {
            "$ref": "#/components/headers/Link"
          }
        }
      },
      "DeliveryNotConfigured": {
        "description": "The server is missing required delivery-provider configuration.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "FORM_DELIVERY_NOT_CONFIGURED",
                "message": "Form delivery is not configured.",
                "hint": "Set the FORMSUBMIT_ENDPOINT environment variable in Vercel."
              }
            }
          }
        },
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Link": {
            "$ref": "#/components/headers/Link"
          }
        }
      },
      "DeliveryProviderError": {
        "description": "The configured delivery provider rejected the submission or could not be confirmed.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            },
            "example": {
              "success": false,
              "error": {
                "code": "DELIVERY_CONFIRMATION_FAILED",
                "message": "Unable to confirm delivery.",
                "hint": "Try again later. The delivery provider may be temporarily unavailable."
              }
            }
          }
        },
        "headers": {
          "API-Version": {
            "$ref": "#/components/headers/ApiVersion"
          },
          "X-API-Version": {
            "$ref": "#/components/headers/XApiVersion"
          },
          "Deprecation": {
            "$ref": "#/components/headers/Deprecation"
          },
          "Link": {
            "$ref": "#/components/headers/Link"
          }
        }
      }
    },
    "headers": {
      "ApiVersion": {
        "description": "Current API major version for this response.",
        "schema": {
          "type": "string",
          "example": "1"
        }
      },
      "XApiVersion": {
        "description": "Compatibility API version header for clients that inspect X-prefixed metadata.",
        "schema": {
          "type": "string",
          "example": "1"
        }
      },
      "Deprecation": {
        "description": "Indicates whether this endpoint is deprecated. Active v1 endpoints return false.",
        "schema": {
          "type": "string",
          "enum": [
            "false",
            "true"
          ],
          "example": "false"
        }
      },
      "Sunset": {
        "description": "HTTP date when a deprecated endpoint may stop working. Present only after deprecation is announced.",
        "schema": {
          "type": "string",
          "format": "date-time",
          "example": "Wed, 31 Dec 2027 23:59:59 GMT"
        }
      },
      "Link": {
        "description": "Link to versioning/deprecation policy, and when applicable migration documentation.",
        "schema": {
          "type": "string",
          "example": "<https://heraldlab.si/developers#versioning-policy>; rel=\"deprecation\"; type=\"text/html\""
        }
      }
    }
  }
}
