API Client Contracts
todos.md exposes the hosted API as machine-readable contracts so agents can plan calls before they mutate work. The public OpenAPI document covers HTTP clients, and the docs catalog covers API, CLI, MCP, and SDK surfaces with schemas, permissions, tenant requirements, and examples.
platform-todos api get /api/v1/openapi.json --jsonplatform-todos docs catalog --surface api --jsonplatform-todos docs catalog --surface api --exposure-profile read-only --jsonContract Sources
Use /api/v1/openapi.json when you need a standard OpenAPI 3.1 document for typed HTTP clients. It includes path parameters, x-organization-id, Idempotency-Key, auth schemes, request bodies, and response schemas generated from the same catalog as the live docs.
Use /api/v1/docs/catalog when an agent needs a broader map of available surfaces. The catalog returns schemaVersion, availableProfiles, surfaces, schemas, and per-operation permissions. Profiles such as read-only, agent-safe, and admin let agents choose only the operations they are allowed to run.
TypeScript Fetch Example
type DocsSurface = "api" | "cli" | "mcp" | "sdk";
interface CatalogOperation {
id: string;
surface: DocsSurface;
name: string;
description: string;
inputSchema: Record<string, unknown>;
outputSchema: Record<string, unknown>;
permissions: {
auth: string;
profile: string;
scopes: string[];
tenantContext: boolean;
};
}
interface DocsSurfaceResponse {
profile: string;
surface: DocsSurface;
count: number;
operations: CatalogOperation[];
}
async function getApiCatalog(apiKey: string): Promise<DocsSurfaceResponse> {
const response = await fetch("https://todos.md/api/v1/docs/catalog/api?profile=agent-safe", {
headers: {
accept: "application/json",
authorization: `Bearer ${apiKey}`,
},
});
if (!response.ok) throw new Error(`catalog request failed: ${response.status}`);
return await response.json() as DocsSurfaceResponse;
}
Mutating Safely
Hosted mutations accept Idempotency-Key. Generate one per logical operation and reuse it on retries.
interface CreateTaskResponse {
id: string;
title: string;
status?: string;
}
async function createTask(apiKey: string, organizationId: string): Promise<CreateTaskResponse> {
const response = await fetch("https://todos.md/api/tasks", {
method: "POST",
headers: {
accept: "application/json",
authorization: `Bearer ${apiKey}`,
"content-type": "application/json",
"idempotency-key": "launch-copy-001",
"x-organization-id": organizationId,
},
body: JSON.stringify({
title: "Review launch checklist",
tags: ["launch", "agent"],
}),
});
if (!response.ok) throw new Error(`task create failed: ${response.status}`);
return await response.json() as CreateTaskResponse;
}