vertet.ai

API Documentation

Convert any web page or PDF into clean markdown over a simple REST API.

Quick start

  1. Create an API key in your account settings. Keys are prefixed nct_ and available on every plan.
  2. Send the key as a Bearer token on every request.
  3. POST a URL and receive markdown in the response.
curl -X POST "https://vertet.ai/api/v1/conversions" \
  -H "Authorization: Bearer nct_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/article"}'

Authentication

All authenticated requests use the Authorization header with your API key as a Bearer token:

Authorization: Bearer nct_your_api_key

Keep keys secret — they carry your account's quota and access. Revoke a key any time from settings.

Base URL

https://vertet.ai/api/v1

Endpoints

POST/conversionsConvert a URL or PDF to markdown
GET/conversionsList your conversions (paginated)
GET/conversions/{id}Fetch a single conversion
GET/conversions/by-urlResolve by URL + short id (auto-refreshes)
DELETE/conversions/{id}Delete a conversion
GET/projectsList projects
POST/projectsCreate a project

POST /conversions accepts a JSON body: { "url": "…", "force_refresh": false }. A successful, uncached crawl counts as one conversion against your monthly quota; cache hits do not. Set force_refresh: true to bypass the cache and re-crawl now (this also counts toward your quota).

GET /conversions supports pagination and sorting: page (≥ 1), limit (1–100, default 20), search, sort_by (fetched_at · word_count · status) and sort_dir (asc · desc).

GET /conversions/by-url requires the url and short_id query parameters, and re-crawls the source automatically once it is past your plan's freshness interval.

Example response

{
  "id": "8f3c…",
  "url": "https://example.com/article",
  "title": "Example article",
  "markdown_content": "# Example article\n\n...",
  "word_count": 1240,
  "status": "completed",
  "fetched_at": "2026-05-25T10:00:00Z",
  "short_id": "ab12-cd34-ef56",
  "cached": false
}

Extraction modes & formats

Reads are free — no crawl, no quota — so you can request different views of a stored conversion. Add mode and format query params to GET /conversions/{id} or GET /conversions/by-url. Unknown values fall back to the default.

modeReturns
contentBest extraction (default) — full markdown.
cleanClean article extraction — boilerplate stripped.
fullFull-page extraction — keeps structural links and sections.
outlineHeading hierarchy only, as a nested list.
tablesOnly the tables.
listsOnly the lists.

format is markdown (default) or json. With format=json, the response includes a structured object: { title, url, headings, links, tables, lists, word_count, markdown }.

# Heading map (outline) as markdown
curl "https://vertet.ai/api/v1/conversions/{id}?mode=outline" \
  -H "Authorization: Bearer nct_your_api_key"

# Structured JSON — headings, links, tables, lists
curl "https://vertet.ai/api/v1/conversions/{id}?format=json" \
  -H "Authorization: Bearer nct_your_api_key"

Permanent share links accept the same params, so no API key is needed for a public conversion — e.g. /raw/{short_id}/{url}?mode=tables.

Code examples

Python

import httpx

resp = httpx.post(
    "https://vertet.ai/api/v1/conversions",
    headers={"Authorization": "Bearer nct_your_api_key"},
    json={"url": "https://example.com/article"},
)
data = resp.json()
print(data["markdown_content"])

JavaScript

const res = await fetch("https://vertet.ai/api/v1/conversions", {
  method: "POST",
  headers: {
    "Authorization": "Bearer nct_your_api_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com/article" }),
});
const data = await res.json();
console.log(data.markdown_content);

Use it from an MCP client

nectr-mcp is a Model Context Protocol server for your library. Add it to any MCP-capable assistant or editor, and the model can search, read and save pages on its own, private pages included, instead of you pasting links into the chat. It uses your API key, so the same plan limits apply.

Add this to your client's MCP configuration (Node.js 20 or newer), then restart it:

{
  "mcpServers": {
    "nectr": {
      "command": "npx",
      "args": ["-y", "nectr-mcp"],
      "env": {
        "NECTR_API_KEY": "nct_your_api_key",
        "NECTR_URL": "https://vertet.ai"
      }
    }
  }
}
ToolWhat the model can do
search_libraryFind saved pages by title or URL. Returns summaries, not full pages.
get_pageRead one page's markdown, with when it was last fetched.
convert_urlSave a new page, optionally into a project. Counts toward your quota.
list_projectsList your projects and their public llms.txt links.

The server never deletes anything, but it is only as safe as its key. MCP clients store the key in plain text in their config file, and the key itself has the same API access as your account. Create a separate key for each client, and revoke it from settings if a device is lost.

Rate limits & quota

API requests share your account's monthly conversion quota — there is no separate API pool. A per-minute rate limit (per key) protects against bursts:

“Pages kept fresh” is how many of your saved pages stay on the auto-refresh schedule. Past that number your oldest pages stop re-crawling — nothing is deleted, they stay saved and readable at their permanent link, they just hold their last version.

PlanRate limitConversions / monthPages kept fresh
Free10 / min10050
Builder60 / min10,0001,000

Error codes

401Missing or invalid API key.
402Monthly conversion limit reached — upgrade or wait for reset.
422Invalid request, or the URL could not be converted — including pages that need a sign-in, which nectr cannot read.
429Rate limit exceeded — retry after the Retry-After header.
503Converter temporarily at capacity — retry after a few seconds.

Markdown output

Each conversion returns a title heading, a metadata block (source URL, conversion time, refresh interval), and the cleaned content — navigation, ads, and boilerplate stripped, with links and images preserved. Authenticated links auto-refresh on access once they pass your plan's freshness interval.