#API & SDK
Use curl.md directly over HTTP or through the published TypeScript SDK.
#HTTP API
The simplest HTTP interface is the hosted curl.md/<url> path:
curl curl.md/developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch?objective=streaming+response+body&keywords=ReadableStream,getReader"This is useful for quick integrations, shell scripts, and server-side fetches.
The public /api surface also includes experimental routes for auth, API keys, organizations, invites, members, and more.
Browser shortcut
You can also use curl.md in your browser by adding curl.md/ in front of any URL. For example, curl.md/example.com
#TypeScript SDK
Use the curl.md npm package when you want a typed client in TypeScript.
#Install
Install curl.md with your favorite package manager:
npm i curl.mdUsing Unreleased Commits
Commits are continuously released via pkg.pr.new and can be installed using the pull request number or short commit ID.
npm i https://pkg.pr.new/curl.md@123When using unreleased commits, please keep in mind there can be breaking changes, especially for pull requests.
#Usage
Create a typed curl.md client, then call fetch with a URL and request options.
import { createClient } from 'curl.md'
const client = createClient()
const res = await client.fetch('docs.github.com/en/webhooks/webhook-events-and-payloads', {
keywords: ['pull_request'],
objective: 'pull request webhook event payload and actions',
})
const json = await res.json()The SDK gives you typed access to request options like objective, keywords, mode, fresh, and token.
The lower-level client.api key exposes experimental /api routes directly.
#Request Options
Use these options with the HTTP API query string or the TypeScript SDK.
#objective
Use objective to narrow the response to content relevant to a specific goal.
HTTP also accepts the aliases o and q.
#keywords
Use keywords to pre-filter the page before extraction.
In HTTP, send them as a comma-separated string.
HTTP also accepts the alias k.
#mode
Use mode to control the extraction model when objective is set.
Supported values are smart and rush.
HTTP also accepts the alias m.
#fresh
Use fresh to bypass cache and force a fresh fetch.
In HTTP, you can send fresh=true or just include ?fresh.
HTTP also accepts the alias f.
#token
Use token in the SDK to send an API key as a Bearer token.
For raw HTTP requests, use the Authorization header instead.
#Authentication
Authenticated requests can use a Bearer token through the Authorization header.
#API Keys
For server-side apps, CI, and other non-interactive integrations, prefer an API key.
Create one from the CLI:
curl.md auth logincurl.md token create my-appIf you want an organization-scoped token, switch to that organization before creating it:
curl.md org switch acmecurl.md token create ciThen send the token as a Bearer token over HTTP:
curl curl.md/example.com -H 'Authorization: Bearer curlmd_xxx'Or pass it to the TypeScript SDK per request:
import { createClient } from 'curl.md'
const client = createClient()
const res = await client.fetch('example.com', {
token: process.env.CURLMD_API_KEY,
})API keys also work through the token or t query parameter when sending headers is inconvenient, though Authorization is recommended.
If you are using session-based auth instead of an API key and need to act within a specific organization, send x-organization-id as well.
#Response Format
The hosted HTTP endpoint returns markdown by default:
curl curl.md/example.comThat response uses text/markdown and returns the final markdown document directly.
If you prefer JSON, send Accept: application/json:
curl curl.md/example.com -H 'Accept: application/json'The JSON shape is:
{
"content": "# Example\n..."
}#Response Headers
Successful fetch responses include useful metadata headers:
x-cache— whether the response was a cacheHITorMISSx-request-id— request identifier for debuggingx-tokens-count— estimated token count for the final responsex-tokens-saved— estimated tokens saved versus the source contentx-cost-mills— request cost in millsx-credits-remaining— remaining prepaid credits, when available
#Error Handling
Errors are returned as JSON with a stable string code and a human-readable message.
Some errors include extra fields, like validation issues.
{
"code": "invalid_api_key",
"message": "Invalid API key"
}In the TypeScript SDK, narrow on res.status before reading res.json().
That gives you endpoint-specific error types in TypeScript.
const res = await client.fetch('example.com')
switch (res.status) {
case 200:
return await res.json()
case 400: {
const json = await res.json()
console.error(json.code) // "validation_error"
return
}
case 502: {
const json = await res.json()
console.error(json.code) // "fetch_failed" | "ai_failed"
return
}
}#Rate Limiting
On the main fetch endpoint, free usage is rate limited and returns 429 with code rate_limit_exceeded when exceeded.
- Standard fetches:
100/houranonymous,1,000/hourauthenticated - Objective queries:
3/houranonymous,10/hourauthenticated - Paid usage skips these rate limits
Higher limits
Sign up for a free account for higher usage limits.
Successful responses include rate-limit headers:
x-ratelimit-limitx-ratelimit-remainingx-ratelimit-reset
Rate-limited responses also include retry-after.
#When to use the API/SDK
- Use the HTTP API for quick fetches from browsers, scripts, and simple integrations.
- Use the TypeScript SDK when you want typed request options and status-aware responses in app code. For example, tool plugins, like the OpenCode plugin and Pi extension.
- Use the CLI when you want shell workflows, local auth, and token or organization management.
Last updated: May 5 3:02 PM