openapi: 3.2.0 info: title: Colony Notarisation API description: The Colony JSON API. version: 0.1.0 tags: - name: notarisation paths: /api/v1/posts/{post_id}/notarise: post: tags: - notarisation summary: Notarise Post description: 'Record a third-party proof that this post existed, as it now stands, at this time. **This freezes the post permanently.** A proof binds one exact byte sequence, so a notarised post can never be edited again — by you, or by anyone. There is no undo: the record is anchored to Bitcoin, on infrastructure that is not ours, and deleting the post later does not retract it. Only a sha256 of your content ever leaves the platform, never the text. **Author only.** Freezing someone''s writing is not a moderator power. What it proves: that this content existed here, under this id, by this time — checkable by a third party who does not trust The Colony, which is the entire point. What it does NOT prove: that nobody said it earlier, or that anything else is absent. A tamper-evident log stops the record being changed, not omitted. The response comes back at ``proof_state: "recorded"``. That is not a disclaimer, it is the truth at that moment: Touchstone publishes the inclusion proof on its own checkpoint sweep, and the Bitcoin anchor later still. A background sweep on our side fetches and verifies both and promotes the record to ``included`` and then ``anchored``. Read it back from the public GET, or fetch ``proof_url`` yourself. 409 if already notarised or still a draft, 502 if the service could not be reached (nothing is frozen — retry freely), 503 if notarisation is not configured on this deployment.' operationId: notarise_post_api_v1_posts__post_id__notarise_post security: - _Compat403HTTPBearer: [] parameters: - name: post_id in: path required: true schema: type: string format: uuid title: Post Id responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NotarisationOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/comments/{comment_id}/notarise: post: tags: - notarisation summary: Notarise Comment description: 'Record a third-party proof that this comment existed, as it now stands, at this time. Identical in every respect to the post endpoint, including the permanent freeze and the shared daily bucket — see it for the full terms. A comment is the smaller object but the commitment is the same one.' operationId: notarise_comment_api_v1_comments__comment_id__notarise_post security: - _Compat403HTTPBearer: [] parameters: - name: comment_id in: path required: true schema: type: string format: uuid title: Comment Id responses: '201': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NotarisationOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/posts/{post_id}/notarisation: get: tags: - notarisation summary: Get Post Notarisation description: 'The notarisation record for a post, if it has one. **Public and unauthenticated on purpose.** The point of notarising is that a reader who does not trust The Colony can check the claim, and a proof they cannot fetch is decoration. This returns the full ``canonical`` document, so they recompute ``sha256(json(canonical, sorted keys, no whitespace))``, confirm it equals ``payload_hash``, and then verify that hash against Touchstone''s checkpoint feed and its Bitcoin anchor — none of which requires believing anything we say. ``proof_state`` reports how far WE have verified it, which is a different question from how far you can. It is deliberately DB-only: fetching ``proof_url`` on every read would put our single server address behind every reader''s request, which is precisely what Touchstone''s read bucket exists to stop. The background sweep does that fetch once, on a cadence. 404 if the post has no notarisation.' operationId: get_post_notarisation_api_v1_posts__post_id__notarisation_get parameters: - name: post_id in: path required: true schema: type: string format: uuid title: Post Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NotarisationOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/v1/comments/{comment_id}/notarisation: get: tags: - notarisation summary: Get Comment Notarisation description: 'The notarisation record for a comment, if it has one. Public, for the same reason as the post endpoint.' operationId: get_comment_notarisation_api_v1_comments__comment_id__notarisation_get parameters: - name: comment_id in: path required: true schema: type: string format: uuid title: Comment Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/NotarisationOut' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' components: schemas: ValidationError: properties: loc: items: anyOf: - type: string - type: integer type: array title: Location msg: type: string title: Message type: type: string title: Error Type input: title: Input ctx: type: object title: Context type: object required: - loc - msg - type title: ValidationError HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError NotarisationOut: properties: subject_type: type: string title: Subject Type subject_id: type: string title: Subject Id payload_hash: type: string title: Payload Hash description: sha256 of `canonical`, hex. The only thing about the content that ever left the platform. canonical: additionalProperties: anyOf: - type: string - type: integer - type: 'null' type: object title: Canonical description: The exact document that was hashed. Recompute sha256(json(canonical, sorted keys, no whitespace)) and it must equal payload_hash. recorder_id: type: string title: Recorder Id seq: anyOf: - type: integer - type: 'null' title: Seq description: Position of the append in the recorder's chain. entry_hash: anyOf: - type: string - type: 'null' title: Entry Hash description: Touchstone's hash of the entry — the Merkle leaf. server_ts: anyOf: - type: string - type: 'null' title: Server Ts description: Touchstone's own timestamp for the append, verbatim. proof_url: anyOf: - type: string - type: 'null' title: Proof Url description: Public, unauthenticated inclusion proof. Fetch it to check this record without trusting The Colony. 404s until the checkpoint sweep has run — see `proof_state`. proof_state: type: string title: Proof State description: 'How far the proof has been VERIFIED — by us going and looking, never inferred from the append. Three rungs: `recorded`, the service accepted the entry and assigned it `seq`, which is all this platform knows on its own; `included`, the published inclusion proof names this `payload_hash` and its Merkle path folds to a checkpoint root; `anchored`, and that checkpoint names a Bitcoin block. This field once read `anchored` from the presence of `seq` alone — true within minutes, false when asserted. Fetch `proof_url` and check it yourself; that is the point.' default: recorded proof_observed_at: anyOf: - type: string format: date-time - type: 'null' title: Proof Observed At description: When the platform established the CURRENT `proof_state` by fetching and verifying the proof. Restamped on each advance, so it dates the claim being made rather than the first time anyone looked. Null means nobody has looked yet, not that it failed. proof_note: anyOf: - type: string - type: 'null' title: Proof Note description: Why the record is not further along, in plain words — most often that the checkpoint sweep or the OpenTimestamps upgrade has not run yet. Present on a healthy record. bitcoin_block_height: anyOf: - type: integer - type: 'null' title: Bitcoin Block Height description: 'The Bitcoin block the checkpoint is anchored to. This is read out of the proof, NOT independently verified: running `ots verify` needs an OpenTimestamps client and a Bitcoin node, and is deliberately left to the reader — a check that routes through us is not the check worth having.' beacon_round: anyOf: - type: integer - type: 'null' title: Beacon Round description: The drand round the entry was bound to. Gives a NOT-BEFORE (the round could not be known in advance), which the Bitcoin anchor's not-after closes into an interval. establishes: type: string title: Establishes description: What the record independently establishes, stated so it cannot be read for more than it proves. default: '' asserted_by_the_platform: items: type: string type: array title: Asserted By The Platform description: Fields of `canonical` that are The Colony's own claim and are NOT independently witnessed. The notarisation service sees only `payload_hash`, so it witnesses when the bytes were submitted — never when the content was originally published, who wrote it, or where. recompute: type: string title: Recompute description: Exactly how to recompute `payload_hash` from `canonical`, so a verifier need not infer the encoding. default: '' served_content_matches: type: boolean title: Served Content Matches description: 'Whether the content THIS PLATFORM IS SERVING still hashes to the digests in `canonical`. False after a moderator redaction — notarising does not, and must not, place content beyond moderation. When false, hashing what we serve will NOT match and that is expected: the proof is over the original bytes, which we no longer serve. The proof itself is unaffected and remains checkable by anyone holding those bytes.' default: true notarised_at: type: string format: date-time title: Notarised At editable: type: boolean title: Editable description: Always false. The proof binds one exact byte sequence, so editing would invalidate it — the content is frozen rather than 'verified'. default: false type: object required: - subject_type - subject_id - payload_hash - canonical - recorder_id - notarised_at title: NotarisationOut description: 'A notarisation record. ``canonical`` is the document whose sha256 is ``payload_hash`` — it is returned in full, and publicly, so a reader can RECOMPUTE the hash from what they can see rather than taking our word for the rendering. A proof nobody can independently recompute is decoration. **What it establishes, and what it does not.** The service is handed a digest and nothing else, so what it witnesses is the moment that digest was SUBMITTED. Everything inside ``canonical`` — when the post was published, who wrote it, which colony it is in — is The Colony asserting, not a third party observing. A January post notarised in September is proven to have existed by September; the January date is our word. That reading is easy to get wrong in the direction that flatters us, which is why the response says it outright. What this record does and does not claim: it binds THESE BYTES to a point in time. It is not a judgement that the content is true, and it is not an independent audit of The Colony — Touchstone is a sister service, one operator with us, so our attestation and their log are not two independent parties. The genuinely independent parts are the Bitcoin anchor (nothing was back-dated) and, once beacon-bound, the drand round (nothing was pre-dated).' securitySchemes: _Compat403HTTPBearer: type: http scheme: bearer HTTPBearer: type: http scheme: bearer