{
  "openapi": "3.1.0",
  "info": {
    "title": "Circadian API",
    "version": "1.0.0",
    "description": "Pay-per-call web data APIs run by a disclosed autonomous AI agent business. Payment is per request via the x402 protocol: call without payment to receive an HTTP 402 challenge, pay in USDC on Base, retry with the X-PAYMENT header. No account needed. Terms: https://circadian-agent.com/terms",
    "contact": {
      "name": "Circadian operator",
      "email": "ops@circadian-agent.com",
      "url": "https://circadian-agent.com"
    }
  },
  "servers": [
    {
      "url": "https://circadian-agent.com"
    }
  ],
  "paths": {
    "/api/extract": {
      "get": {
        "operationId": "extractGet",
        "summary": "Extract a web page to clean Markdown plus metadata",
        "description": "Turns any public web page into clean Markdown plus title, description, links and word count. SSRF guarded, 2MB cap, 10s budget. Costs 0.01 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.01"
          }
        },
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Public http(s) URL of the page to extract",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Extraction result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractResult"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing url input. No charge."
          },
          "422": {
            "description": "Target fetch failed. No charge."
          }
        }
      },
      "post": {
        "operationId": "extractPost",
        "summary": "Extract a web page to clean Markdown plus metadata",
        "description": "Same as GET but the target URL is passed in the JSON body. Costs 0.01 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.01"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public http(s) URL of the page to extract"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Extraction result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExtractResult"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing url input. No charge."
          },
          "422": {
            "description": "Target fetch failed. No charge."
          }
        }
      }
    },
    "/api/meta": {
      "get": {
        "operationId": "metaGet",
        "summary": "Structured page metadata as one JSON",
        "description": "OpenGraph, Twitter card, JSON-LD, RSS and Atom feeds, canonical URL, icons and language for any public URL. Costs 0.005 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.005"
          }
        },
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": true,
            "description": "Public http(s) URL of the page to inspect",
            "schema": {
              "type": "string",
              "format": "uri"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Metadata result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetaResult"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing url input. No charge."
          },
          "422": {
            "description": "Target fetch failed. No charge."
          }
        }
      },
      "post": {
        "operationId": "metaPost",
        "summary": "Structured page metadata as one JSON",
        "description": "Same as GET but the target URL is passed in the JSON body. Costs 0.005 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "0.005"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "Public http(s) URL of the page to inspect"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Metadata result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MetaResult"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing url input. No charge."
          },
          "422": {
            "description": "Target fetch failed. No charge."
          }
        }
      }
    },
    "/api/brief": {
      "get": {
        "operationId": "briefGet",
        "summary": "Order an async researched technical brief",
        "description": "Researched, cited 500 to 800 word brief on your topic, written by a disclosed AI agent and delivered async within 36 hours. Returns a job id and status URL immediately after payment. Costs 3.00 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "3.00"
          }
        },
        "parameters": [
          {
            "name": "topic",
            "in": "query",
            "required": true,
            "description": "Research topic or question, 8 to 2048 characters",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 2048
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BriefJob"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing or invalid topic. No charge."
          },
          "503": {
            "description": "Queue at capacity. No charge."
          }
        }
      },
      "post": {
        "operationId": "briefPost",
        "summary": "Order an async researched technical brief",
        "description": "Same as GET but topic and up to 5 seed URLs are passed in the JSON body. Costs 3.00 USD per call via x402.",
        "x-payment-info": {
          "protocols": [
            "x402"
          ],
          "price": {
            "mode": "fixed",
            "currency": "USD",
            "amount": "3.00"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "topic"
                ],
                "properties": {
                  "topic": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 2048
                  },
                  "urls": {
                    "type": "array",
                    "maxItems": 5,
                    "items": {
                      "type": "string",
                      "format": "uri"
                    },
                    "description": "Optional seed URLs to consider"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Job accepted",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BriefJob"
                }
              }
            }
          },
          "402": {
            "description": "Payment required. Body and Payment-Required header carry the x402 challenge with accepted payment requirements (USDC on Base, exact scheme)."
          },
          "400": {
            "description": "Missing or invalid topic. No charge."
          },
          "503": {
            "description": "Queue at capacity. No charge."
          }
        }
      }
    },
    "/api/jobs/{id}": {
      "get": {
        "operationId": "jobStatus",
        "summary": "Free status check for an async job",
        "description": "No payment needed. Returns status (awaiting_payment, queued, working, delivered, rejected, refunded) and, when delivered, the brief result with sources.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Job record"
          },
          "404": {
            "description": "Unknown job id"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ExtractResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "url": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string"
          },
          "httpStatus": {
            "type": "integer"
          },
          "contentType": {
            "type": "string"
          },
          "truncated": {
            "type": "boolean"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "markdown": {
            "type": "string"
          },
          "wordCount": {
            "type": "integer"
          },
          "links": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "text": {
                  "type": "string"
                },
                "href": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "MetaResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "httpStatus": {
            "type": "integer"
          },
          "truncated": {
            "type": "boolean"
          },
          "url": {
            "type": "string"
          },
          "finalUrl": {
            "type": "string"
          },
          "lang": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "canonical": {
            "type": [
              "string",
              "null"
            ]
          },
          "openGraph": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "twitter": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "jsonLd": {
            "type": "array",
            "items": {}
          },
          "feeds": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "href": {
                  "type": "string"
                },
                "type": {
                  "type": "string"
                },
                "title": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "icons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "BriefJob": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "jobId": {
            "type": "string",
            "format": "uuid"
          },
          "statusUrl": {
            "type": "string",
            "format": "uri"
          },
          "sla": {
            "type": "string"
          },
          "topic": {
            "type": "string"
          },
          "note": {
            "type": "string"
          }
        }
      }
    }
  }
}
