EveryPage OAuth API
The OAuth API from EveryPage — 3 operation(s) for oauth.
The OAuth API from EveryPage — 3 operation(s) for oauth.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/everypage-co:everypage-co-oauth-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: EveryPage OAuth API
description: 'Upload documents and get trackable share links programmatically. Authenticate with a personal API key (create one at https://everypage.co/account under API keys) or an OAuth 2.0 access token, sent as a bearer token. Every error under /api/v1 is an RFC 9457 problem document (application/problem+json) - branch on its `code`.
Versioning: /api/v1 is the contract - changes inside a version are additive only, and anything scheduled to go away carries Deprecation (RFC 9745) and Sunset (RFC 8594) headers with at least six months'' notice (https://everypage.co/docs/developers/versioning; no active deprecations). Rate limits: 120 requests per minute per bearer token, advertised on every response in RateLimit and RateLimit-Policy (IETF structured fields) plus X-RateLimit-*, with Retry-After on 429. OAuth 2.0 server metadata: https://everypage.co/.well-known/oauth-authorization-server.'
version: 1.1.0
termsOfService: https://everypage.co/terms
x-deprecation-policy:
url: https://everypage.co/docs/developers/versioning
minimumNoticeDays: 180
signals:
- Deprecation
- Sunset
- Link rel=deprecation
activeDeprecations: []
contact:
email: support@everypage.co
servers:
- url: https://everypage.co
security:
- bearerAuth: []
tags:
- name: OAuth
paths:
/oauth/authorize:
get:
tags:
- OAuth
summary: Authorization endpoint (Authorization Code + PKCE)
operationId: oauthAuthorize
description: Browser endpoint, not an API call - send the user here to obtain consent for a registered OAuth client. Signed-out users are bounced through login first. On approval it redirects to `redirect_uri` with `?code=` (and `?state=`); protocol errors (`unsupported_response_type`, `invalid_request` for a missing/non-S256 challenge, `invalid_scope`) redirect back with `?error=`. An unknown `client_id` or an unregistered `redirect_uri` cannot be redirected and answers a plain-text 400 instead. PKCE S256 is mandatory; authorization codes are single-use and valid for 5 minutes.
security: []
parameters:
- name: response_type
in: query
required: true
schema:
type: string
enum:
- code
description: Always `code`.
- name: client_id
in: query
required: true
schema:
type: string
description: The registered OAuth client id (`epc_...`).
- name: redirect_uri
in: query
required: true
schema:
type: string
description: Must exactly match a redirect URI registered for the client.
- name: scope
in: query
required: true
schema:
type: string
description: Space-delimited; every scope must be allowed for the client.
- name: state
in: query
required: false
schema:
type: string
description: Opaque CSRF value echoed back on the redirect.
- name: code_challenge
in: query
required: true
schema:
type: string
description: PKCE challenge (RFC 7636).
- name: code_challenge_method
in: query
required: true
schema:
type: string
enum:
- S256
description: Only `S256` is accepted.
responses:
'302':
description: Redirect to the consent screen, login, or back to redirect_uri with code/error.
'400':
description: Unknown OAuth client, or a `redirect_uri` that is not registered for the client. Plain text - there is no trusted redirect target to send the error to.
content:
text/plain:
schema:
type: string
/oauth/token:
post:
tags:
- OAuth
summary: Token endpoint
operationId: oauthToken
description: 'Exchanges an authorization code (with the PKCE `code_verifier`) or a refresh token for tokens. Client auth via HTTP Basic or body params; confidential clients must present `client_secret`. Refresh tokens rotate: each refresh returns a new `refresh_token` and retires the previous one (replaying a retired token revokes the whole family); pass `scope` to down-scope. Errors are RFC 6749 JSON documents.'
security: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
grant_type:
type: string
enum:
- authorization_code
- refresh_token
code:
type: string
redirect_uri:
type: string
code_verifier:
type: string
refresh_token:
type: string
scope:
type: string
description: Optional down-scope on refresh.
client_id:
type: string
client_secret:
type: string
description: Confidential clients only.
responses:
'200':
description: Token response
content:
application/json:
schema:
type: object
properties:
access_token:
type: string
example: ep_at_...
token_type:
type: string
example: Bearer
expires_in:
type: integer
refresh_token:
type: string
scope:
type: string
'400':
description: '`invalid_request`, `invalid_grant` (unknown, used, expired or PKCE-mismatched code; revoked or rotated refresh token) or `unsupported_grant_type`.'
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthError'
'401':
description: '`invalid_client` - unknown `client_id`, or a wrong or missing `client_secret` for a confidential client.'
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthError'
/oauth/revoke:
post:
tags:
- OAuth
summary: Revoke a token (RFC 7009)
operationId: oauthRevoke
description: Revoke an access or refresh token issued to your OAuth client. Client authentication as on the token endpoint (HTTP Basic or body params). Unknown tokens still answer 200; only client-authentication failures error.
security: []
requestBody:
required: true
content:
application/x-www-form-urlencoded:
schema:
type: object
properties:
token:
type: string
token_type_hint:
type: string
enum:
- access_token
- refresh_token
client_id:
type: string
client_secret:
type: string
responses:
'200':
description: Always returns 200 (empty body), even for unknown tokens.
'400':
description: invalid_request (unparseable form)
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthError'
'401':
description: invalid_client (missing or unknown client_id, or a wrong client_secret)
content:
application/json:
schema:
$ref: '#/components/schemas/OAuthError'
components:
schemas:
OAuthError:
type: object
description: RFC 6749 error document returned by the /oauth/token and /oauth/revoke endpoints.
properties:
error:
type: string
example: invalid_client
error_description:
type: string
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: 'An API key (ep_live_...) or OAuth access token (ep_at_...) sent as `Authorization: Bearer <token>`. API keys hold every scope; OAuth tokens are limited to the scopes granted at consent.'
oauth2:
type: oauth2
description: Authorization Code + PKCE (S256 only, no plain). Client authentication on the token and revoke endpoints via HTTP Basic or `client_id`/`client_secret` body params; public clients send `client_id` alone. Refresh tokens rotate on every refresh (the previous one is retired; reusing it revokes the token family) and may be down-scoped with `scope`. Each operation lists the scope it requires.
flows:
authorizationCode:
authorizationUrl: https://everypage.co/oauth/authorize
tokenUrl: https://everypage.co/oauth/token
refreshUrl: https://everypage.co/oauth/token
scopes:
files:read: See your files and share links
files:write: Upload, configure, and delete files
readership:read: See who read your documents
webhooks:manage: Create, list, test, and delete webhook subscriptions
profile: See your account email and plan
manageToken:
type: http
scheme: bearer
bearerFormat: EveryPage manage token
description: 'The `manageToken` returned by an anonymous upload or a Canva import, sent as `Authorization: Bearer <manageToken>`. Bound to one file; valid for 30 days and only while that file remains unclaimed - once the file is claimed into an account, token calls answer 404. Token callers act at the free tier: plan-gated settings answer 403 and content replacement (Pro) is always refused. Accepted ONLY by PUT /api/v1/files/{uuid}/settings and POST /api/v1/files/{uuid}/content; every other operation answers 401 to it. Not the `claimToken` (a different credential that attaches the file to an account).'
canvaJwt:
type: http
scheme: bearer
bearerFormat: JWT
description: A Canva Apps SDK user token (`auth.getCanvaUserToken()`), verified against Canva JWKS. Accepted only by the /api/v1/canva/* operations, which are called by the EveryPage Canva app; it is not an EveryPage credential and no other operation accepts it.
externalDocs:
url: https://everypage.co/developers
description: Developer guide