{
  "openapi": "3.1.0",
  "info": {
    "title": "Tokimi Timestamp PQ-v2",
    "version": "0.2.0",
    "description": "ML-DSA-87 signatures and SHA-512 across target digests, private commitments, Merkle nodes, signed-head preimages, archives and public key pins. Original files, digest and salt stay local. Operator clock; independent existence upper bounds unavailable. drand is not in this profile. Legacy v1 history is read-only."
  },
  "servers": [
    {
      "url": "https://tokimi.space/api/timestamps/v1"
    }
  ],
  "paths": {
    "/pq/v2/health": {
      "get": {
        "summary": "API capability status",
        "responses": {
          "200": {
            "description": "API version and evidence boundary; not a guarantee that signing is healthy"
          }
        }
      }
    },
    "/requests": {
      "post": {
        "summary": "Durably admit a commitment",
        "security": [
          {
            "TimestampKey": []
          }
        ],
        "description": "Stable admission gateway. Explicit commit/2 profile required. Save the 64-byte salt and Idempotency-Key locally before submission. A 202 is not signed inclusion; follow the Location header into the PQ-v2 read namespace. Legacy single-field/64-hex requests return 410 when authenticated with a v2 credential. No downgrade.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,128}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "profile",
                  "commitment"
                ],
                "properties": {
                  "commitment": {
                    "$ref": "#/components/schemas/Hex64"
                  },
                  "profile": {
                    "const": "tokimi-timestamp/commit/2"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Previously completed idempotent request; receipt is published",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Admission"
                }
              }
            }
          },
          "202": {
            "description": "Durable admission awaiting signed and archived inclusion",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Admission"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Same client/key was used with a different commitment"
          },
          "410": {
            "description": "Legacy profile retired; never retry by weakening the algorithm."
          },
          "413": {
            "description": "Body exceeds 1024 bytes"
          },
          "415": {
            "description": "application/json required"
          },
          "429": {
            "description": "Admission quota reached"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/pq/v2/requests/{id}": {
      "get": {
        "summary": "Retrieve the authenticated client's operation",
        "security": [
          {
            "TimestampKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{16,128}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pending or complete",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Admission"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Unknown operation or different owner"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/pq/v2/receipts/{index}": {
      "get": {
        "summary": "Public receipt with stable original inclusion head",
        "parameters": [
          {
            "$ref": "#/components/parameters/Index"
          }
        ],
        "responses": {
          "200": {
            "description": "Signed inclusion receipt; no independent upper bound",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Receipt"
                }
              }
            }
          },
          "404": {
            "description": "Not published"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/pq/v2/log/keys": {
      "get": {
        "summary": "Advertised public key and log metadata",
        "description": "A key fetched here is not an independently selected receiver trust pin.",
        "responses": {
          "200": {
            "description": "Log identity, key, tree size and operator-clock boundary"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/pq/v2/log/sth": {
      "get": {
        "summary": "Latest published signed tree head",
        "responses": {
          "200": {
            "description": "Published head",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignedTreeHead"
                }
              }
            }
          },
          "404": {
            "description": "No published head"
          },
          "503": {
            "$ref": "#/components/responses/Unavailable"
          }
        }
      }
    },
    "/pq/v2/log/sth/{size}": {
      "get": {
        "summary": "Historical published signed tree head",
        "parameters": [
          {
            "name": "size",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published head"
          },
          "404": {
            "description": "No published head at that size"
          }
        }
      }
    },
    "/pq/v2/log/entries": {
      "get": {
        "summary": "Public entries in [start,end), at most 100",
        "parameters": [
          {
            "name": "start",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "end",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Published commitments and operator registration times; no private target/salt/owner mapping"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/pq/v2/log/proof/inclusion": {
      "get": {
        "summary": "SHA-512 tree inclusion path against an exact published prefix",
        "parameters": [
          {
            "name": "log_index",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "tree_size",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Path plus exact index and size; receiver supplies a valid matching root"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/pq/v2/log/proof/consistency": {
      "get": {
        "summary": "SHA-512 tree prefix consistency path",
        "parameters": [
          {
            "name": "first",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          },
          {
            "name": "second",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Consistency hashes; receiver verifies both matching roots"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "TimestampKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Dedicated 64-byte CSPRNG bearer (86 canonical base64url chars), stored only as a SHA-512 digest on the API. Separate v2 credential; legacy tokens cannot create new records."
      }
    },
    "parameters": {
      "Index": {
        "name": "index",
        "in": "path",
        "required": true,
        "schema": {
          "type": "integer",
          "minimum": 0,
          "maximum": 9007199254740991
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid fixed-format input or range"
      },
      "Unauthorized": {
        "description": "Missing, expired, revoked or invalid timestamp credential"
      },
      "Unavailable": {
        "description": "Disabled, signing/archival failure, capacity, clock rollback or recovery required; preserve original request for retry"
      }
    },
    "schemas": {
      "Admission": {
        "type": "object",
        "required": [
          "request_id",
          "status"
        ],
        "properties": {
          "request_id": {
            "type": "string"
          },
          "status": {
            "enum": [
              "pending",
              "completed"
            ]
          },
          "receipt": {
            "$ref": "#/components/schemas/Receipt"
          }
        }
      },
      "SignedTreeHead": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "body",
          "signature",
          "public_key"
        ],
        "properties": {
          "body": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "schema",
              "log_id",
              "key_id",
              "key_epoch",
              "signature_algorithm",
              "hash_algorithm",
              "tree_size",
              "timestamp",
              "root_hash"
            ],
            "properties": {
              "schema": {
                "const": "tokimi-timestamp-sth/v2"
              },
              "log_id": {
                "const": "tokimi.space/timestamp/pq-2"
              },
              "key_id": {
                "type": "string",
                "pattern": "^sha512:[a-f0-9]{128}$"
              },
              "key_epoch": {
                "const": 1
              },
              "signature_algorithm": {
                "const": "ML-DSA-87"
              },
              "hash_algorithm": {
                "const": "SHA-512"
              },
              "tree_size": {
                "type": "integer",
                "minimum": 1,
                "maximum": 9007199254740991
              },
              "timestamp": {
                "type": "string",
                "format": "date-time"
              },
              "root_hash": {
                "$ref": "#/components/schemas/Hex64"
              }
            },
            "description": "Exact fixed-order transcript in spec-v2.md. Pure FIPS204 ML-DSA-87 with empty context, not HashML-DSA. Algorithm selection is not FIPS140 module validation."
          },
          "signature": {
            "type": "string",
            "minLength": 6170,
            "maxLength": 6170,
            "pattern": "^[A-Za-z0-9_-]+$"
          },
          "public_key": {
            "type": "string",
            "minLength": 3456,
            "maxLength": 3456,
            "pattern": "^[A-Za-z0-9_-]+$"
          }
        }
      },
      "Receipt": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schema",
          "log_index",
          "entry",
          "inclusion_proof",
          "inclusion_sth",
          "external_evidence"
        ],
        "properties": {
          "schema": {
            "const": "tokimi-timestamp-receipt/v2"
          },
          "log_index": {
            "type": "integer",
            "minimum": 0
          },
          "entry": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "commitment",
              "registered_at"
            ],
            "properties": {
              "commitment": {
                "$ref": "#/components/schemas/Hex64"
              },
              "registered_at": {
                "type": "string",
                "format": "date-time"
              }
            }
          },
          "inclusion_proof": {
            "type": "object",
            "required": [
              "tree_size",
              "hashes"
            ],
            "properties": {
              "tree_size": {
                "type": "integer",
                "minimum": 1
              },
              "hashes": {
                "type": "array",
                "maxItems": 64,
                "items": {
                  "$ref": "#/components/schemas/Hex64"
                }
              }
            }
          },
          "inclusion_sth": {
            "$ref": "#/components/schemas/SignedTreeHead"
          },
          "external_evidence": {
            "type": "array",
            "maxItems": 0
          }
        }
      },
      "Hex64": {
        "type": "string",
        "pattern": "^[a-f0-9]{128}$"
      }
    }
  }
}
