{
  "openapi": "3.1.0",
  "info": {
    "title": "proofd.id Premium API",
    "version": "1.0.0",
    "summary": "Hash-first timestamping API for premium proofd.id integrations.",
    "description": "The proofd.id Premium API lets external systems create and read timestamp records using SHA-256 hashes. Files never need to be uploaded to the API. Clients compute the hash locally and send the fingerprint plus file metadata. All responses use a stable JSON error envelope with a request_id for support and incident correlation."
  },
  "servers": [
    {
      "url": "https://proofd.id",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Timestamps",
      "description": "Create, list, inspect, and download timestamp evidence."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/api/v1/timestamps": {
      "get": {
        "tags": [
          "Timestamps"
        ],
        "summary": "List timestamps",
        "operationId": "listTimestamps",
        "parameters": [
          {
            "in": "query",
            "name": "status",
            "schema": {
              "type": "string",
              "enum": [
                "all",
                "confirmed",
                "pending",
                "failed"
              ],
              "default": "all"
            },
            "description": "Optional status filter."
          },
          {
            "in": "query",
            "name": "before",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Cursor pagination token from a previous `next_cursor` value."
          },
          {
            "in": "query",
            "name": "limit",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50
            },
            "description": "Optional page size. The API enforces a hard cap of 50."
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated owner-scoped timestamp list.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTimestampListResponse"
                },
                "examples": {
                  "default": {
                    "value": {
                      "data": [
                        {
                          "id": "7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d",
                          "certificate_id": "TS-0K7M6X",
                          "sha256_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                          "filename": "msa-v3.pdf",
                          "file_size_bytes": 248331,
                          "file_type": "application/pdf",
                          "status": "pending",
                          "blockchain_tx": null,
                          "bitcoin_block": null,
                          "confirmed_at": null,
                          "created_at": "2026-04-13T18:42:11.000Z",
                          "thumbnail_url": null,
                          "branding_snapshot": null,
                          "certificate_url": "https://proofd.id/cert/TS-0K7M6X",
                          "verify_url": "https://proofd.id/verify/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                          "ots_url": "/api/v1/timestamps/7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d/ots"
                        }
                      ],
                      "total_count": 1,
                      "next_cursor": "2026-04-13T18:42:11.000Z"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "500": {
            "$ref": "#/components/responses/Error500"
          }
        }
      },
      "post": {
        "tags": [
          "Timestamps"
        ],
        "summary": "Create a timestamp",
        "operationId": "createTimestamp",
        "parameters": [
          {
            "in": "header",
            "name": "Idempotency-Key",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "required": false,
            "description": "Recommended for safe retries of create requests."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTimestampRequest"
              },
              "examples": {
                "default": {
                  "value": {
                    "sha256_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                    "filename": "msa-v3.pdf",
                    "file_size_bytes": 248331,
                    "file_type": "application/pdf"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Timestamp resource created.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTimestampResource"
                },
                "examples": {
                  "default": {
                    "value": {
                      "id": "7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d",
                      "certificate_id": "TS-0K7M6X",
                      "sha256_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                      "filename": "msa-v3.pdf",
                      "file_size_bytes": 248331,
                      "file_type": "application/pdf",
                      "status": "pending",
                      "blockchain_tx": null,
                      "bitcoin_block": null,
                      "confirmed_at": null,
                      "created_at": "2026-04-13T18:42:11.000Z",
                      "thumbnail_url": null,
                      "branding_snapshot": null,
                      "certificate_url": "https://proofd.id/cert/TS-0K7M6X",
                      "verify_url": "https://proofd.id/verify/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                      "ots_url": "/api/v1/timestamps/7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d/ots"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "409": {
            "description": "Duplicate or idempotency conflict.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiV1ErrorResponse"
                },
                "examples": {
                  "duplicate": {
                    "value": {
                      "error": {
                        "code": "DUPLICATE_TIMESTAMP",
                        "message": "This file was already timestamped (certificate: TS-0K7M6X)",
                        "request_id": "4740c1a9-6c63-4b74-9e1d-baa1f2546f17"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "500": {
            "$ref": "#/components/responses/Error500"
          },
          "502": {
            "description": "OpenTimestamps provider failure.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiV1ErrorResponse"
                },
                "examples": {
                  "default": {
                    "value": {
                      "error": {
                        "code": "OTS_PROVIDER_ERROR",
                        "message": "Failed to create OpenTimestamps proof",
                        "request_id": "5fb512a7-2832-4e2c-bbb2-b4bd507b5d9f"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/timestamps/{id}": {
      "get": {
        "tags": [
          "Timestamps"
        ],
        "summary": "Get a timestamp by ID",
        "operationId": "getTimestamp",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Timestamp UUID returned at creation time."
          }
        ],
        "responses": {
          "200": {
            "description": "Timestamp resource.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiTimestampResource"
                },
                "examples": {
                  "default": {
                    "value": {
                      "id": "7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d",
                      "certificate_id": "TS-0K7M6X",
                      "sha256_hash": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                      "filename": "msa-v3.pdf",
                      "file_size_bytes": 248331,
                      "file_type": "application/pdf",
                      "status": "pending",
                      "blockchain_tx": null,
                      "bitcoin_block": null,
                      "confirmed_at": null,
                      "created_at": "2026-04-13T18:42:11.000Z",
                      "thumbnail_url": null,
                      "branding_snapshot": null,
                      "certificate_url": "https://proofd.id/cert/TS-0K7M6X",
                      "verify_url": "https://proofd.id/verify/9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
                      "ots_url": "/api/v1/timestamps/7b4d95f8-91cb-4e1c-b7d6-1eb9f0de4e8d/ots"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "500": {
            "$ref": "#/components/responses/Error500"
          }
        }
      }
    },
    "/api/v1/timestamps/{id}/ots": {
      "get": {
        "tags": [
          "Timestamps"
        ],
        "summary": "Download the OTS proof file",
        "operationId": "downloadTimestampOts",
        "parameters": [
          {
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            },
            "description": "Timestamp UUID returned at creation time."
          }
        ],
        "responses": {
          "200": {
            "description": "Binary OTS proof payload.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              },
              "Content-Disposition": {
                "schema": {
                  "type": "string"
                },
                "description": "Attachment filename for the `.ots` proof."
              }
            },
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "500": {
            "$ref": "#/components/responses/Error500"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "proofd API key",
        "description": "Send the premium API key as `Authorization: Bearer proofd_live_...`."
      }
    },
    "headers": {
      "XRequestId": {
        "schema": {
          "type": "string",
          "format": "uuid"
        },
        "description": "Request correlation ID included on every API response."
      }
    },
    "schemas": {
      "BrandSnapshot": {
        "type": "object",
        "nullable": true,
        "properties": {
          "version": {
            "type": "integer",
            "const": 1
          },
          "brand_name": {
            "type": "string"
          },
          "brand_logo_path": {
            "type": [
              "string",
              "null"
            ]
          },
          "brand_primary_color": {
            "type": "string"
          },
          "brand_support_email": {
            "type": [
              "string",
              "null"
            ]
          },
          "brand_website": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "version",
          "brand_name",
          "brand_logo_path",
          "brand_primary_color",
          "brand_support_email",
          "brand_website"
        ]
      },
      "TimestampStatus": {
        "type": "string",
        "enum": [
          "pending",
          "confirmed",
          "failed"
        ]
      },
      "CreateTimestampRequest": {
        "type": "object",
        "properties": {
          "sha256_hash": {
            "type": "string",
            "pattern": "^[0-9a-fA-F]{64}$"
          },
          "filename": {
            "type": "string",
            "minLength": 1
          },
          "file_size_bytes": {
            "type": "integer",
            "minimum": 1
          },
          "file_type": {
            "type": "string"
          }
        },
        "required": [
          "sha256_hash",
          "filename",
          "file_size_bytes"
        ],
        "additionalProperties": false
      },
      "ApiTimestampResource": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "certificate_id": {
            "type": "string"
          },
          "sha256_hash": {
            "type": "string"
          },
          "filename": {
            "type": "string"
          },
          "file_size_bytes": {
            "type": "integer"
          },
          "file_type": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/TimestampStatus"
          },
          "blockchain_tx": {
            "type": [
              "string",
              "null"
            ]
          },
          "bitcoin_block": {
            "type": [
              "integer",
              "null"
            ]
          },
          "confirmed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "thumbnail_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "branding_snapshot": {
            "$ref": "#/components/schemas/BrandSnapshot"
          },
          "certificate_url": {
            "type": "string",
            "format": "uri"
          },
          "verify_url": {
            "type": "string",
            "format": "uri"
          },
          "ots_url": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "certificate_id",
          "sha256_hash",
          "filename",
          "file_size_bytes",
          "file_type",
          "status",
          "blockchain_tx",
          "bitcoin_block",
          "confirmed_at",
          "created_at",
          "thumbnail_url",
          "branding_snapshot",
          "certificate_url",
          "verify_url",
          "ots_url"
        ]
      },
      "ApiTimestampListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiTimestampResource"
            }
          },
          "total_count": {
            "type": "integer"
          },
          "next_cursor": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "data",
          "total_count"
        ]
      },
      "ApiV1ErrorDetail": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string"
          },
          "message": {
            "type": "string"
          },
          "request_id": {
            "type": "string",
            "format": "uuid"
          }
        },
        "required": [
          "code",
          "message",
          "request_id"
        ]
      },
      "ApiV1ErrorResponse": {
        "type": "object",
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ApiV1ErrorDetail"
          }
        },
        "required": [
          "error"
        ]
      }
    },
    "responses": {
      "Error400": {
        "description": "Validation or request-shape error.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "INVALID_SHA256_HASH",
                    "message": "Invalid sha256_hash - must be 64 hex characters",
                    "request_id": "4c27c056-a3a1-4522-8a49-3a3066f8d3f7"
                  }
                }
              }
            }
          }
        }
      },
      "Error401": {
        "description": "Authentication error.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "AUTHENTICATION_REQUIRED",
                    "message": "A valid Bearer API key is required.",
                    "request_id": "c80df3c4-3ab6-46ef-9de7-f6095eb66c62"
                  }
                }
              }
            }
          }
        }
      },
      "Error403": {
        "description": "Plan entitlement error.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "PLAN_NOT_ENTITLED",
                    "message": "API access requires a Pro or Business plan.",
                    "request_id": "35d420b5-6fd1-4094-ac10-481eed434c68"
                  }
                }
              }
            }
          }
        }
      },
      "Error404": {
        "description": "Unknown or unavailable resource.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "TIMESTAMP_NOT_FOUND",
                    "message": "Timestamp not found.",
                    "request_id": "3da5aaec-c743-4318-ad86-4075b95d37d6"
                  }
                }
              }
            }
          }
        }
      },
      "Error429": {
        "description": "Rate-limited request.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          },
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until retry is allowed."
          },
          "X-RateLimit-Limit": {
            "schema": {
              "type": "integer"
            },
            "description": "Applied limit for the bucket that was exceeded."
          },
          "X-RateLimit-Remaining": {
            "schema": {
              "type": "integer"
            },
            "description": "Remaining requests in the current bucket. Returns `0` on throttle."
          },
          "X-RateLimit-Reset": {
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Bucket reset time in ISO-8601 format."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Too many API requests. Please retry later.",
                    "request_id": "c715b7ec-4d84-4f4d-b683-4ab62b2f43c1"
                  }
                }
              }
            }
          }
        }
      },
      "Error500": {
        "description": "Internal platform error.",
        "headers": {
          "X-Request-Id": {
            "$ref": "#/components/headers/XRequestId"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApiV1ErrorResponse"
            },
            "examples": {
              "default": {
                "value": {
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "Failed to load timestamps.",
                    "request_id": "bb9a76f0-b666-4069-8b6a-eb3b1b640581"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}