Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
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.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/granite-md:granite-md-publish-api"
All apis
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.
Get an API 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 Specification
openapi: 3.2.0
info:
title: Granite Publish API
version: 1.0.0
summary: REST API for Granite clients, bots, and integrations.
description: 'Conventions (apply to every operation; see PLAN.md 3.2 and 3.6):
- **Base URL** `https://api.granite.md`. All public operations live under `/v1`.
After Phase 6 ships, `/v1` changes are additive only.
- **Errors** use RFC 9457 problem details (`application/problem+json`, schema `Problem`).
The `type` URI is `https://granite.md/problems/`; `code` refines it for programmatic handling.
Every response carries `X-Request-ID`, also echoed as `request_id` in problems.
- **Pagination** is cursor based. List operations accept `cursor` and `limit` and return
`{ "items": [...], "next_cursor": "..." }`. `next_cursor` is absent on the last page.
Cursors are opaque; clients must not parse or build them.
- **Idempotency**: non-idempotent `POST` operations accept an `Idempotency-Key` header
(1-255 printable ASCII). Repeating a request with the same key and body within 24 hours
returns the original response; the same key with a different body returns `409` with
code `idempotency_key_reused`.
- **IDs** are UUIDv7 strings. **Timestamps** are RFC 3339 in UTC.
- **Authentication**: `Authorization: Bearer ` with a session access token,
a personal API token (`gr_pat_...`), or an OAuth access token. Scopes are listed per operation.
- **Rate limits**: each personal API token may make 600 requests a minute. Over the limit
the API answers `429` with code `token_rate_limited` and a `Retry-After` header (seconds).'
license:
name: Proprietary
identifier: LicenseRef-Proprietary
servers:
- url: https://api.granite.md
description: Production
- url: http://localhost:8080
description: Local development
security:
- bearerAuth: []
tags:
- name: Publish
description: Public pages of published notes.
paths:
/v1/vaults/{vault_id}/files/{file_id}/publish:
parameters:
- $ref: '#/components/parameters/VaultID'
- $ref: '#/components/parameters/FileID'
put:
operationId: publishNote
tags:
- Publish
summary: Publish a note as a public page
description: 'Makes the note readable by anyone with the link at `/p/{slug}` (rendered on the server
from the note''s current version and sanitized). Calling it again changes the address or
password. Needs vault admin access; the plan limits how many notes are published
(`plan_limit_published_notes`).'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PublishRequest'
responses:
'200':
description: The page.
content:
application/json:
schema:
$ref: '#/components/schemas/PublishedNote'
default:
$ref: '#/components/responses/Error'
delete:
operationId: unpublishNote
tags:
- Publish
summary: Take a note's page down
responses:
'204':
description: The page answers 404 from now on.
default:
$ref: '#/components/responses/Error'
/v1/vaults/{vault_id}/published:
parameters:
- $ref: '#/components/parameters/VaultID'
get:
operationId: listPublished
tags:
- Publish
summary: Published notes in a vault
responses:
'200':
description: Published notes.
content:
application/json:
schema:
$ref: '#/components/schemas/PublishedList'
default:
$ref: '#/components/responses/Error'
components:
headers:
RequestID:
description: Identifier of this request, for support and log correlation.
schema:
type: string
parameters:
VaultID:
name: vault_id
in: path
required: true
schema:
type: string
format: uuid
FileID:
name: file_id
in: path
required: true
schema:
type: string
format: uuid
schemas:
PublishedList:
type: object
required:
- items
properties:
items:
type: array
items:
$ref: '#/components/schemas/PublishedNote'
Problem:
type: object
description: RFC 9457 problem details.
required:
- type
- title
- status
properties:
type:
type: string
format: uri
examples:
- https://granite.md/problems/conflict
title:
type: string
status:
type: integer
format: int32
detail:
type: string
instance:
type: string
code:
type: string
description: Machine-readable refinement of `type`, for example `version_conflict`.
request_id:
type: string
errors:
type: array
description: Per-field validation errors.
items:
$ref: '#/components/schemas/FieldError'
PublishedNote:
type: object
required:
- file_id
- path
- slug
- url
- protected
properties:
file_id:
type: string
format: uuid
path:
type: string
slug:
type: string
url:
type: string
format: uri
protected:
type: boolean
description: The page asks for a password.
FieldError:
type: object
required:
- field
- detail
properties:
field:
type: string
description: JSON path of the invalid field, for example `ops[2].path`.
detail:
type: string
PublishRequest:
type: object
properties:
slug:
type: string
pattern: ^[a-z0-9][a-z0-9-]{2,63}$
description: The page address; omitted keeps the current one or picks a random one.
password:
type: string
maxLength: 256
writeOnly: true
description: Omitted keeps the current password; "" removes it.
responses:
Error:
description: Error response.
headers:
X-Request-ID:
$ref: '#/components/headers/RequestID'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Session access token, personal API token, or OAuth access token.