{
  "openapi": "3.1.0",
  "info": {
    "title": "notepad.page REST API",
    "version": "0.3.0",
    "summary": "REST endpoints for agent-managed notepad.page publishing.",
    "description": "notepad.page gives a user one private, durable notepad at <name>.notepad.page. Agents publish complete single-file HTML documents, recall and update existing pages, and share only when explicitly requested. Owner-minted np_ agent tokens provide scoped, expiring REST access for unattended publishing."
  },
  "servers": [
    {
      "url": "https://api.notepad.page"
    }
  ],
  "externalDocs": {
    "description": "Canonical agent instructions",
    "url": "https://notepad.page/llms.txt"
  },
  "tags": [
    {
      "name": "Discovery",
      "description": "Machine discovery surfaces."
    },
    {
      "name": "Waitlist",
      "description": "Invite-only beta enrollment."
    },
    {
      "name": "Agent Tokens",
      "description": "Sponsor-managed credentials for unattended REST clients."
    },
    {
      "name": "Pages",
      "description": "Private-by-default page publishing and lifecycle."
    },
    {
      "name": "Sharing",
      "description": "Explicit sharing and share-token management."
    },
    {
      "name": "Memory",
      "description": "Recall over the notepad memory index."
    },
    {
      "name": "Safety",
      "description": "Quota and abuse-report surfaces."
    }
  ],
  "paths": {
    "/": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Return this OpenAPI JSON document.",
        "responses": {
          "200": {
            "description": "OpenAPI document",
            "content": {}
          }
        }
      }
    },
    "/ask": {
      "get": {
        "tags": [
          "Discovery"
        ],
        "summary": "Retrieve canonical notepad.page knowledge for a question.",
        "description": "Public, deterministic keyword retrieval over the same typed corpus that generates llms.txt and llms-full.txt. Returns source sections for the calling agent to compose an answer. Rate limited to 60 questions per caller IP per hour.",
        "parameters": [
          {
            "name": "question",
            "in": "query",
            "required": true,
            "description": "Question about notepad.page.",
            "schema": {
              "type": "string",
              "maxLength": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Relevant knowledge sections",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "question",
                    "sections",
                    "relatedSectionTitles",
                    "source",
                    "fallback"
                  ],
                  "properties": {
                    "question": {
                      "type": "string"
                    },
                    "sections": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 5,
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "title",
                          "body"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "relatedSectionTitles": {
                      "type": "array",
                      "maxItems": 3,
                      "items": {
                        "type": "string"
                      }
                    },
                    "source": {
                      "type": "string",
                      "format": "uri"
                    },
                    "fallback": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Question missing or too long",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Caller IP rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Discovery"
        ],
        "summary": "Retrieve canonical notepad.page knowledge for a question.",
        "description": "JSON-body equivalent of GET /ask. No LLM runs server-side; the calling agent composes the answer from the returned sections.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "question": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "additionalProperties": false,
                "required": [
                  "question"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Relevant knowledge sections",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "question",
                    "sections",
                    "relatedSectionTitles",
                    "source",
                    "fallback"
                  ],
                  "properties": {
                    "question": {
                      "type": "string"
                    },
                    "sections": {
                      "type": "array",
                      "minItems": 1,
                      "maxItems": 5,
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "title",
                          "body"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "body": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": false
                      }
                    },
                    "relatedSectionTitles": {
                      "type": "array",
                      "maxItems": 3,
                      "items": {
                        "type": "string"
                      }
                    },
                    "source": {
                      "type": "string",
                      "format": "uri"
                    },
                    "fallback": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Question missing or too long",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Caller IP rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/waitlist": {
      "post": {
        "tags": [
          "Waitlist"
        ],
        "summary": "Join the invite-only beta waitlist.",
        "description": "Rate limited to 5 waitlist posts per IP per day. US/rest-of-world beta entries use the global signup budget and receive a claim token only for a new waitlist entry. EU/EEA/UK/Switzerland entries are recorded as regional interest and do not receive claim tokens during beta.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 320
                  },
                  "use_case": {
                    "type": "string",
                    "maxLength": 1000
                  },
                  "agent_client": {
                    "type": "string",
                    "maxLength": 120
                  }
                },
                "additionalProperties": false,
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Waitlist pending response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "claim_token": {
                      "type": "string",
                      "description": "Shown once only for a new waitlist entry."
                    },
                    "message": {
                      "type": "string"
                    },
                    "region": {
                      "type": "string",
                      "enum": [
                        "eu",
                        "uk"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending_confirmation",
                        "regional_interest"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "429": {
            "description": "Rate limited or beta capacity reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/invite/request": {
      "post": {
        "tags": [
          "Waitlist"
        ],
        "summary": "Request a capacity-gated or referred beta invite.",
        "description": "Rate limited to 5 requests per caller IP per day. If a configured beta seat is available, reserves it and emails a single-use 14-day invite. A valid referral consumes one of the active referrer's two invites and bypasses only the seat cap. Unknown, exhausted, or suspended codes fall back to normal capacity; self-referrals are rejected. All daily invite, email, identity, and per-IP safeguards still apply. Invite codes are never returned.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 320
                  },
                  "referralCode": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "Optional publisher referral code from a shared get_invite_to_share prompt."
                  },
                  "turnstileToken": {
                    "type": "string",
                    "maxLength": 2048
                  }
                },
                "additionalProperties": false,
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Invite request result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "invited",
                        "waitlisted",
                        "publisher",
                        "invite_redeemed",
                        "approved"
                      ]
                    },
                    "inviteExpiresAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "publisherStatus": {
                      "type": "string"
                    },
                    "region": {
                      "type": "string",
                      "enum": [
                        "eu",
                        "uk"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Invalid email or Turnstile verification",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Caller IP or signup budget limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/waitlist/status": {
      "get": {
        "tags": [
          "Waitlist"
        ],
        "summary": "Check waitlist status by claim token.",
        "description": "This intentionally accepts a claim token, not an email address.",
        "parameters": [
          {
            "name": "claim_token",
            "in": "query",
            "required": true,
            "description": "Claim token returned by POST /waitlist.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Waitlist status",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status"
                  ],
                  "properties": {
                    "status": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Missing claim token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "No waitlist entry for that claim token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tokens": {
      "post": {
        "tags": [
          "Waitlist"
        ],
        "summary": "Redeem an invite code.",
        "description": "Current beta behavior marks the invite code redeemed. Publisher creation and OAuth grant/token issuance continue through the MCP/OAuth flow.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "invite_code": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "additionalProperties": false,
                "required": [
                  "invite_code"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Invite redeemed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "status",
                    "publisherCreation"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "invite_redeemed"
                      ]
                    },
                    "publisherCreation": {
                      "type": "string",
                      "enum": [
                        "stub"
                      ]
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Invite code invalid or already used",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Invite code expired after 14 days",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/report": {
      "post": {
        "tags": [
          "Safety"
        ],
        "summary": "Report a potentially abusive page.",
        "description": "Reports are IP-hashed, deduplicated by reporter hash, and rate limited to 10 per IP per minute. One distinct report suspends a link-shared page pending appeal. Public pages are prioritized immediately and suspended after 3 distinct reports. Private-page reports are ignored.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pageId": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "reason": {
                    "type": "string",
                    "maxLength": 500
                  }
                },
                "additionalProperties": false,
                "required": [
                  "pageId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Report accepted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "received"
                  ],
                  "properties": {
                    "received": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "429": {
            "description": "Report rate limit reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/appeals": {
      "post": {
        "tags": [
          "Safety"
        ],
        "summary": "Submit an appeal from an emailed owner link.",
        "description": "Validates the signed, expiring email token and derives page and publisher scope from that token. Only one pending appeal may exist for a suspended page.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "token": {
                    "type": "string",
                    "maxLength": 4096
                  },
                  "message": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "additionalProperties": false,
                "required": [
                  "token",
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing pending appeal",
            "content": {}
          },
          "201": {
            "description": "Pending appeal created",
            "content": {}
          },
          "400": {
            "description": "Appeal link invalid or expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Page is not suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/agent-tokens": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Agent Tokens"
        ],
        "summary": "List agent tokens for this notepad.",
        "description": "Sponsor authentication is required. Agent tokens cannot call this endpoint. Secret values and hashes are never returned.",
        "responses": {
          "200": {
            "description": "Agent token list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "tokens"
                  ],
                  "properties": {
                    "tokens": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AgentToken"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "403": {
            "description": "Sponsor authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Agent Tokens"
        ],
        "summary": "Create a scoped agent token.",
        "description": "Sponsor authentication is required. The np_ secret is returned only in this response and is stored only as a SHA-256 hash.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "publish",
                      "full"
                    ]
                  },
                  "expiresInDays": {
                    "type": "number",
                    "default": 90,
                    "description": "Clamped to 1 through 365 days."
                  }
                },
                "additionalProperties": false,
                "required": [
                  "name",
                  "scope"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Agent token created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "token",
                    "id",
                    "name",
                    "scope",
                    "expiresAt"
                  ],
                  "properties": {
                    "token": {
                      "type": "string",
                      "pattern": "^np_[a-f0-9]{64}$",
                      "description": "Shown once. Store it securely."
                    },
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "scope": {
                      "type": "string",
                      "enum": [
                        "publish",
                        "full"
                      ]
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "403": {
            "description": "Sponsor authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/agent-tokens/{id}": {
      "delete": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Agent Tokens"
        ],
        "summary": "Revoke an agent token.",
        "description": "Sponsor authentication is required. The id must belong to the authenticated publisher.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 128
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Revocation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "revoked"
                  ],
                  "properties": {
                    "revoked": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "403": {
            "description": "Sponsor authentication required",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "summary": "List pages in this notepad.",
        "description": "Returns owner-visible metadata including memory/librarian fields, share state, scan state, pin state, last activity, and gardening expiry projection.",
        "responses": {
          "200": {
            "description": "Page list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "pages"
                  ],
                  "properties": {
                    "pages": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PageMetadata"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      },
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "summary": "Create a new private page.",
        "description": "Publishes one complete single-file HTML document. If slug is omitted, the API derives a readable slug from the title or document title and suffixes collisions. New pages are private by default and pass quota, global publish budget, static scan, content-ban, and memory/librarian gates.",
        "requestBody": {
          "$ref": "#/components/requestBodies/PageCreate"
        },
        "responses": {
          "201": {
            "description": "Created page URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "url",
                    "slug"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "slug": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "413": {
            "description": "HTML or JSON body too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid or blocked HTML",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Page, byte, daily publish, or beta capacity quota reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/shares": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Sharing"
        ],
        "summary": "List active shares.",
        "description": "Returns owner-visible share inventory across the notepad, optionally filtered to one page. Claimed invite URLs are returned for owner reference but flagged as unusable for other recipients.",
        "parameters": [
          {
            "name": "pageId",
            "in": "query",
            "required": false,
            "description": "Optional owner-scoped page id.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Active share inventory",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "shares"
                  ],
                  "properties": {
                    "shares": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ShareInventoryRow"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "404": {
            "description": "Filtered page not found in this notepad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages/publish": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "summary": "Publish an artifact in one call.",
        "description": "Creates or updates a private page. If slug matches an existing page in this notepad, that page is updated. Otherwise, when autoUpdateIfExists is true, owner-private memory recall is used to update only a strong, unambiguous match; weak or missing matches create a new private page. The selected write path still passes quota, global publish budget, static scan, content-ban, and memory/librarian gates.",
        "requestBody": {
          "$ref": "#/components/requestBodies/PagePublish"
        },
        "responses": {
          "200": {
            "description": "Updated existing page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishResponse"
                }
              }
            }
          },
          "201": {
            "description": "Created new page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublishResponse"
                }
              }
            }
          },
          "409": {
            "description": "Archived page must be restored before replacement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "HTML or JSON body too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid or blocked HTML",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Page, byte, daily publish, or beta capacity quota reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Get a page and its HTML.",
        "description": "Fetches owner-visible metadata plus the stored HTML document.",
        "responses": {
          "200": {
            "description": "Page with HTML",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/PageMetadata"
                    },
                    {
                      "type": "object",
                      "required": [
                        "html"
                      ],
                      "properties": {
                        "html": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Page not found in this notepad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "put": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Replace page HTML.",
        "description": "Updates an existing page through the same quota, static scan, content-ban, and memory/librarian gates. Archived pages must be restored first.",
        "requestBody": {
          "$ref": "#/components/requestBodies/PageReplace"
        },
        "responses": {
          "200": {
            "description": "Updated page metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageMetadata"
                }
              }
            }
          },
          "409": {
            "description": "Archived page must be restored before replacement",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "413": {
            "description": "HTML or JSON body too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Invalid or blocked HTML",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Byte, daily publish, or beta capacity quota reached",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Delete a page.",
        "description": "Deletes the page row and its shares from the notepad index.",
        "responses": {
          "200": {
            "description": "Delete result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "deleted"
                  ],
                  "properties": {
                    "deleted": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/rename": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Rename a page title.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "additionalProperties": false,
                "required": [
                  "title"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Renamed page metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageMetadata"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/pin": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Pin or unpin a page.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "pinned": {
                    "type": "boolean"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "pinned"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pinned page metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageMetadata"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/restore": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Pages"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Restore an archived page within the restore window.",
        "description": "Archived HTML remains restorable for 30 days after archive, 60 days total from last activity.",
        "responses": {
          "200": {
            "description": "Restored page metadata",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PageMetadata"
                }
              }
            }
          },
          "410": {
            "description": "Restore window expired",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/share": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Share a page.",
        "description": "Private pages remain owner-only until this succeeds. Every resulting shared view is read-only. Sharing runs the full abuse scan and may block with a relayable 422 reason; a recipient batch runs one scan before minting its links.",
        "requestBody": {
          "$ref": "#/components/requestBodies/Share"
        },
        "responses": {
          "201": {
            "description": "Share details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareResponse"
                }
              }
            }
          },
          "409": {
            "description": "Archived page must be restored before sharing",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Sharing scan blocked the page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/unshare": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Revoke active shares.",
        "description": "Provide shareId to revoke one active share, or omit it to revoke all active shares. The page returns to private when no active shares remain.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "shareId": {
                    "type": "string",
                    "maxLength": 100
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Revocation result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "revoked",
                    "remainingShares"
                  ],
                  "properties": {
                    "revoked": {
                      "type": "boolean"
                    },
                    "remainingShares": {
                      "type": "integer",
                      "minimum": 0
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/rotate": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Sharing"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Rotate the active share token.",
        "description": "Revokes active shares, mints a new one, and runs the sharing scan. If mode is omitted, the existing mode is reused, defaulting private pages to link.",
        "requestBody": {
          "$ref": "#/components/requestBodies/ShareRotate"
        },
        "responses": {
          "200": {
            "description": "New share details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareResponse"
                }
              }
            }
          },
          "409": {
            "description": "Archived page must be restored before rotation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Sharing scan blocked the page",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/pages/{id}/appeal": {
      "post": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Safety"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Page id returned by create, list, recall, or get."
          }
        ],
        "summary": "Appeal a suspended page as its owner.",
        "description": "Publisher scope comes from bearer or signed MCP authentication, never request arguments. Creating a second open appeal is idempotent.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message": {
                    "type": "string",
                    "maxLength": 2000
                  }
                },
                "additionalProperties": false,
                "required": [
                  "message"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Existing pending appeal",
            "content": {}
          },
          "201": {
            "description": "Pending appeal created",
            "content": {}
          },
          "404": {
            "description": "Page not found in this notepad",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Page is not suspended",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/recall": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Memory"
        ],
        "summary": "Recall pages from the notepad memory index.",
        "description": "Searches owner-private memory metadata. Agents should call this before creating a page to decide whether update is more appropriate.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Plain-English search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum hits. Defaults to 6, maximum 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "minScore",
            "in": "query",
            "required": false,
            "description": "Minimum lexical score. Defaults to 0.1.",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Recall hits",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "query",
                    "hits"
                  ],
                  "properties": {
                    "query": {
                      "type": "string"
                    },
                    "hits": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/RecallHit"
                      }
                    }
                  },
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Missing query",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/quota": {
      "get": {
        "security": [
          {
            "bearer": []
          }
        ],
        "tags": [
          "Safety"
        ],
        "summary": "Get quota usage and global beta budget state.",
        "responses": {
          "200": {
            "description": "Quota state",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quota"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Active REST bearer token for a notepad grant, or an owner-minted np_ agent token on routes allowed by its publish or full scope. Agent tokens cannot manage tokens, sessions, sharing, appeals, or invites. MCP clients normally call the MCP worker, which signs internal API assertions instead of forwarding OAuth access tokens."
      }
    },
    "requestBodies": {
      "PageCreate": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "html"
              ],
              "properties": {
                "html": {
                  "type": "string",
                  "maxLength": 2097152,
                  "description": "Complete HTML document. Must start with <!doctype html> or <html> and contain one html element."
                },
                "title": {
                  "type": "string",
                  "maxLength": 200
                },
                "purpose": {
                  "type": "string",
                  "maxLength": 1000
                },
                "project": {
                  "type": "string",
                  "maxLength": 200
                },
                "relatedTo": {
                  "type": "object",
                  "properties": {
                    "supersedes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "maxLength": 200
                      }
                    },
                    "derivedFrom": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "maxLength": 200
                      }
                    }
                  },
                  "additionalProperties": false
                },
                "slug": {
                  "type": "string",
                  "maxLength": 100,
                  "description": "Optional readable slug. Omit to derive one from the title. Reserved and phishing-sensitive terms are rejected."
                }
              },
              "additionalProperties": false
            }
          }
        }
      },
      "PagePublish": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "title",
                "html"
              ],
              "properties": {
                "title": {
                  "type": "string",
                  "maxLength": 200
                },
                "purpose": {
                  "type": "string",
                  "maxLength": 1000
                },
                "html": {
                  "type": "string",
                  "maxLength": 2097152,
                  "description": "Complete HTML document. Must start with <!doctype html> or <html> and contain one html element."
                },
                "slug": {
                  "type": "string",
                  "maxLength": 100,
                  "description": "Optional readable slug. If it matches an existing page in this notepad, that page is updated; otherwise it is used for the new page."
                },
                "autoUpdateIfExists": {
                  "type": "boolean",
                  "default": true,
                  "description": "When true, the API recalls this notepad's memory and updates only a strong, unambiguous title/purpose match."
                }
              },
              "additionalProperties": false
            }
          }
        }
      },
      "PageReplace": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "html"
              ],
              "properties": {
                "html": {
                  "type": "string",
                  "maxLength": 2097152,
                  "description": "Complete HTML document. Must start with <!doctype html> or <html> and contain one html element."
                },
                "title": {
                  "type": "string",
                  "maxLength": 200
                },
                "purpose": {
                  "type": "string",
                  "maxLength": 1000
                },
                "project": {
                  "type": "string",
                  "maxLength": 200
                },
                "relatedTo": {
                  "type": "object",
                  "properties": {
                    "supersedes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "maxLength": 200
                      }
                    },
                    "derivedFrom": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "maxLength": 200
                      }
                    }
                  },
                  "additionalProperties": false
                }
              },
              "additionalProperties": false
            }
          }
        }
      },
      "Share": {
        "required": true,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "mode": {
                  "type": "string",
                  "enum": [
                    "link",
                    "public"
                  ],
                  "description": "link creates an unlisted read-only token URL; public creates a read-only non-token URL and public-index entry."
                },
                "access": {
                  "type": "string",
                  "enum": [
                    "invite",
                    "anyone"
                  ],
                  "description": "For link mode: invite requires verified email; anyone makes the token URL the only access gate."
                },
                "recipients": {
                  "type": "array",
                  "maxItems": 10,
                  "description": "For link invite mode, mint one creation-time email-locked link per recipient.",
                  "items": {
                    "type": "object",
                    "required": [
                      "email"
                    ],
                    "properties": {
                      "email": {
                        "type": "string",
                        "format": "email",
                        "maxLength": 320
                      },
                      "label": {
                        "type": "string",
                        "maxLength": 200
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "expiresAt": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Optional future ISO timestamp."
                },
                "allowedIps": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "description": "Optional IP addresses or CIDR ranges allowed to view the share."
                }
              },
              "additionalProperties": false,
              "required": [
                "mode"
              ]
            }
          }
        }
      },
      "ShareRotate": {
        "required": false,
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "mode": {
                  "type": "string",
                  "enum": [
                    "link",
                    "public"
                  ],
                  "description": "link creates an unlisted read-only token URL; public creates a read-only non-token URL and public-index entry."
                },
                "shareId": {
                  "type": "string",
                  "maxLength": 100,
                  "description": "Optional active share to reissue without revoking the page's other links. Recipient pre-binding is preserved."
                },
                "expiresAt": {
                  "type": "string",
                  "format": "date-time",
                  "description": "Optional future ISO timestamp."
                },
                "allowedIps": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "maxLength": 80
                  },
                  "description": "Optional IP addresses or CIDR ranges allowed to view the share."
                }
              },
              "additionalProperties": false
            }
          }
        }
      }
    },
    "schemas": {
      "PageMetadata": {
        "type": "object",
        "required": [
          "id",
          "slug",
          "url",
          "share",
          "expiry",
          "pinned",
          "contentBytes"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "slug": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "summary": {
            "type": [
              "string",
              "null"
            ]
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "purpose": {
            "type": [
              "string",
              "null"
            ]
          },
          "project": {
            "type": [
              "string",
              "null"
            ]
          },
          "relatedTo": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "supersedes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  },
                  "derivedFrom": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "status": {
            "type": "string"
          },
          "scanStatus": {
            "type": "string"
          },
          "scanProvider": {
            "type": [
              "string",
              "null"
            ]
          },
          "scanDegraded": {
            "type": "boolean"
          },
          "share": {
            "type": "object",
            "required": [
              "mode",
              "allowedIps",
              "activeShares"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "private",
                  "link",
                  "public"
                ]
              },
              "allowedIps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "activeShares": {
                "type": "array",
                "description": "Owner-visible active share state. Viewer email is never exposed.",
                "items": {
                  "type": "object",
                  "required": [
                    "bound",
                    "bound_at"
                  ],
                  "properties": {
                    "bound": {
                      "type": "boolean"
                    },
                    "bound_at": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  },
                  "additionalProperties": false
                }
              }
            },
            "additionalProperties": false
          },
          "lastActivityAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiry": {
            "type": "object",
            "required": [
              "state",
              "archiveAt",
              "purgeAt"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "active",
                  "archived",
                  "persistent",
                  "unknown"
                ]
              },
              "archiveAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "purgeAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            },
            "additionalProperties": false
          },
          "pinned": {
            "type": "boolean"
          },
          "archivedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "persistent": {
            "type": "boolean"
          },
          "contentBytes": {
            "type": "integer",
            "minimum": 0
          },
          "reviewPriority": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": true
      },
      "AgentToken": {
        "type": "object",
        "required": [
          "id",
          "name",
          "scope",
          "created",
          "expires",
          "lastUsed",
          "revoked"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "scope": {
            "type": "string",
            "enum": [
              "publish",
              "full"
            ]
          },
          "created": {
            "type": "string",
            "format": "date-time"
          },
          "expires": {
            "type": "string",
            "format": "date-time"
          },
          "lastUsed": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "revoked": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "PublishResponse": {
        "type": "object",
        "required": [
          "id",
          "url",
          "slug",
          "action",
          "matchedExisting"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "slug": {
            "type": "string"
          },
          "action": {
            "type": "string",
            "enum": [
              "created",
              "updated"
            ]
          },
          "matchedExisting": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "RecallHit": {
        "type": "object",
        "required": [
          "id",
          "score",
          "slug",
          "url",
          "title",
          "shareMode"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "score": {
            "type": "number"
          },
          "matchedTokens": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "slug": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "title": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "keywords": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "purpose": {
            "type": [
              "string",
              "null"
            ]
          },
          "project": {
            "type": [
              "string",
              "null"
            ]
          },
          "relatedTo": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "supersedes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  },
                  "derivedFrom": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 200
                    }
                  }
                },
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "shareMode": {
            "type": "string",
            "enum": [
              "private",
              "link",
              "public"
            ]
          },
          "pinned": {
            "type": "boolean"
          },
          "lastActivityAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "additionalProperties": true
      },
      "ShareResponse": {
        "anyOf": [
          {
            "type": "object",
            "required": [
              "shareId",
              "mode",
              "token",
              "tokenShownOnce",
              "url",
              "expiresAt",
              "allowedIps"
            ],
            "properties": {
              "shareId": {
                "type": "string"
              },
              "mode": {
                "type": "string",
                "enum": [
                  "link",
                  "public"
                ]
              },
              "access": {
                "type": "string",
                "enum": [
                  "invite",
                  "anyone"
                ]
              },
              "token": {
                "type": "string",
                "description": "The share token; its SHA-256 hash remains the lookup key."
              },
              "tokenShownOnce": {
                "type": "boolean"
              },
              "url": {
                "type": "string",
                "format": "uri"
              },
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "allowedIps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "email": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "email"
              },
              "label": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "prebound": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          },
          {
            "type": "object",
            "required": [
              "mode",
              "access",
              "expiresAt",
              "allowedIps",
              "shares"
            ],
            "properties": {
              "mode": {
                "type": "string",
                "enum": [
                  "link"
                ]
              },
              "access": {
                "type": "string",
                "enum": [
                  "invite"
                ]
              },
              "expiresAt": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "allowedIps": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "shares": {
                "type": "array",
                "maxItems": 10,
                "items": {
                  "type": "object",
                  "required": [
                    "shareId",
                    "mode",
                    "token",
                    "tokenShownOnce",
                    "url",
                    "expiresAt",
                    "allowedIps",
                    "email",
                    "label",
                    "prebound"
                  ],
                  "properties": {
                    "shareId": {
                      "type": "string"
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "link",
                        "public"
                      ]
                    },
                    "access": {
                      "type": "string",
                      "enum": [
                        "invite",
                        "anyone"
                      ]
                    },
                    "token": {
                      "type": "string",
                      "description": "The share token; its SHA-256 hash remains the lookup key."
                    },
                    "tokenShownOnce": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    },
                    "expiresAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "allowedIps": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "email": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "email"
                    },
                    "label": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "prebound": {
                      "type": "boolean"
                    }
                  },
                  "additionalProperties": false
                }
              }
            },
            "additionalProperties": false
          }
        ]
      },
      "ShareInventoryRow": {
        "type": "object",
        "required": [
          "shareId",
          "pageSlug",
          "mode",
          "access",
          "prebound",
          "email",
          "label",
          "state",
          "createdAt",
          "expiresAt",
          "allowedIps",
          "url",
          "urlUsable"
        ],
        "properties": {
          "shareId": {
            "type": "string"
          },
          "pageSlug": {
            "type": "string"
          },
          "mode": {
            "type": "string",
            "enum": [
              "public",
              "link"
            ]
          },
          "access": {
            "type": "string",
            "enum": [
              "invite",
              "anyone"
            ]
          },
          "prebound": {
            "type": "boolean"
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "label": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "open",
              "waiting",
              "claimed"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "allowedIps": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "urlUsable": {
            "type": "boolean",
            "description": "False for claimed invite URLs and legacy shares whose token is unavailable."
          }
        },
        "additionalProperties": false
      },
      "Quota": {
        "type": "object",
        "required": [
          "pages",
          "bytes",
          "publishesToday",
          "requestRate",
          "globalBudgets"
        ],
        "properties": {
          "pages": {
            "type": "object",
            "required": [
              "used",
              "limit"
            ],
            "properties": {
              "used": {
                "type": "integer",
                "minimum": 0
              },
              "limit": {
                "type": "integer",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "bytes": {
            "type": "object",
            "required": [
              "used",
              "limit"
            ],
            "properties": {
              "used": {
                "type": "integer",
                "minimum": 0
              },
              "limit": {
                "type": "integer",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "publishesToday": {
            "type": "object",
            "required": [
              "used",
              "limit"
            ],
            "properties": {
              "used": {
                "type": "integer",
                "minimum": 0
              },
              "limit": {
                "type": "integer",
                "minimum": 0
              }
            },
            "additionalProperties": false
          },
          "requestRate": {
            "type": "object",
            "required": [
              "limit",
              "windowSeconds"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "enum": [
                  50
                ]
              },
              "windowSeconds": {
                "type": "integer",
                "enum": [
                  60
                ]
              }
            },
            "additionalProperties": false
          },
          "globalBudgets": {
            "type": "object",
            "required": [
              "publishes",
              "signups"
            ],
            "properties": {
              "publishes": {
                "type": "object",
                "required": [
                  "day",
                  "used",
                  "limit",
                  "remaining"
                ],
                "properties": {
                  "day": {
                    "type": "string"
                  },
                  "used": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "remaining": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "additionalProperties": false
              },
              "signups": {
                "type": "object",
                "required": [
                  "day",
                  "used",
                  "limit",
                  "remaining"
                ],
                "properties": {
                  "day": {
                    "type": "string"
                  },
                  "used": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 0
                  },
                  "remaining": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "additionalProperties": false
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    }
  },
  "x-notepad-policy": {
    "beta": "invite-only",
    "html": {
      "document": "complete single-file HTML document",
      "maxBytes": 2097152
    },
    "quotas": {
      "pages": 25,
      "activeHtmlBytes": 20971520,
      "publishesPerDay": 200,
      "authenticatedRequestsPerMinute": 50
    },
    "lifecycle": {
      "archiveAfterDaysFromLastActivity": 30,
      "hardPurgeAfterDaysFromLastActivity": 60,
      "restoreWindowDaysAfterArchive": 30
    },
    "visibility": {
      "default": "private",
      "shareModes": [
        "link",
        "public"
      ],
      "ipAllowlistField": "allowedIps"
    }
  }
}