Documentation

Public HTTP API

Programmatic access to tools, categories, tags, posts, and AI generation via REST

DirStarter ships with a public REST API at /api/v1 for programmatic management of your directory. It's powered by oRPC and @orpc/openapi, so the same routers drive the internal RPC endpoint (/api/rpc), the public REST surface, and your server components.

Sensitive endpoints (metrics, users, reports, ads, media uploads) are marked internal and never appear on the public surface — they stay reachable only through a signed-in dashboard session.

Available resources

Each resource exposes list, create, update, delete, lookup, and duplicate operations where applicable. Tools also include a scheduled listing endpoint.

ResourceBase pathNotes
Tools/api/v1/toolsFilter by status, paginate, sort, duplicate
Categories/api/v1/categoriesFull CRUD + lookup
Tags/api/v1/tagsFull CRUD + lookup
Posts/api/v1/postsFilter by status, paginate, sort
AI/api/v1/ai/*Requires AI_GATEWAY_API_KEY; returns 501 when unset

Media uploads are not exposed on the public API. Upload images through the dashboard, or set faviconUrl and screenshotUrl to publicly accessible URLs when creating or updating records.

API keys

Access is authenticated with per-user API keys, not a shared environment secret. Issue and revoke keys from the API keys page in your dashboard (/app/api-keys, admin only).

When you create a key:

  • The full token (prefixed dk_) is shown once — copy it immediately, it is never displayed again.
  • Only a short prefix and a SHA-256 hash of the token are stored, so a database dump never exposes usable keys.
  • You can set an optional expiry, and revoke any key at any time.

A key acts on behalf of the user who created it and inherits that user's role permissions. Revoking a key, banning its owner, or letting it expire immediately stops it from authenticating.

There is no API_KEY environment variable. The public API is always mounted; an endpoint simply returns 401 Unauthorized until a valid key is presented.

Authentication

Every request must include the token as a Bearer credential:

Authorization: Bearer dk_xxxxxxxxxxxx…

Missing, malformed, expired, or revoked keys return 401 Unauthorized.

Quickstart

# List tools
curl https://your-site.com/api/v1/tools \
  -H "Authorization: Bearer $DIRSTARTER_KEY"

# Create a tool (server assigns id)
curl -X POST https://your-site.com/api/v1/tools \
  -H "Authorization: Bearer $DIRSTARTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Example", "websiteUrl": "https://example.com" }'

# Partially update a tool
curl -X PATCH https://your-site.com/api/v1/tools/{id} \
  -H "Authorization: Bearer $DIRSTARTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tagline": "Updated tagline" }'

# Delete tools
curl -X DELETE https://your-site.com/api/v1/tools \
  -H "Authorization: Bearer $DIRSTARTER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "ids": ["cuid1", "cuid2"] }'

OpenAPI spec & interactive docs

The OpenAPI document is the machine-readable contract for the public API. Use it to generate typed clients, Postman collections, MCP tool definitions, or agent integrations without reading router source.

The spec declares a global BearerAuth security scheme (http + bearer, format API Key). Scalar reads that metadata and renders an auth prompt so integrators can store the key once and send it on every Try-it-out request. All data endpoints enforce the same Bearer check server-side.

The docs UI and the spec JSON are reachable without a key so Scalar can load in a browser; every data operation still requires Bearer auth at runtime.

EndpointDescription
GET /api/v1/openapi.jsonGenerated OpenAPI 3.1 document
GET /api/v1/docsScalar-rendered interactive API reference

Open /api/v1/docs, click Authentication, enter one of your API keys as the Bearer token, then use Try-it-out on any operation.

curl https://your-site.com/api/v1/openapi.json

Query parameters

List endpoints accept pagination, sorting, date filters, and array filters. For array filters (e.g. status on GET /tools and GET /posts), repeat the key for each value per the OpenAPI default. A single scalar is also accepted for convenience.

ParameterDescription
pagePage number (default 1)
perPageItems per page (default 25, max 100)
sortComma-separated field:asc or field:desc pairs (e.g. createdAt:desc,name:asc)
from / toISO date strings to filter by date range
nameText search filter (tools, categories, tags, posts)
statusRepeatable status filter (tools, posts)
# Multiple values: repeat the key
curl "https://your-site.com/api/v1/tools?status=Published&status=Scheduled" \
  -H "Authorization: Bearer $DIRSTARTER_KEY"

# Single value: scalar is accepted and treated as a one-element array
curl "https://your-site.com/api/v1/tools?status=Published" \
  -H "Authorization: Bearer $DIRSTARTER_KEY"

# Sort and paginate
curl "https://your-site.com/api/v1/tools?sort=createdAt:desc&page=2&perPage=50" \
  -H "Authorization: Bearer $DIRSTARTER_KEY"

Rate limits

Each API key gets its own bucket: 600 requests / hour. When exceeded, the server returns 429 Too Many Requests with a Retry-After header.

Error shape

Errors are JSON with the following structure:

{ "code": "NOT_FOUND", "message": "Tool not found" }
CodeHTTPWhen
UNAUTHORIZED401Missing or invalid API key
FORBIDDEN403Authenticated but not allowed
NOT_FOUND404Resource or route does not exist
BAD_REQUEST400Invalid input (Zod validation failure)
TOO_MANY_REQUESTS429Rate limit exceeded
NOT_IMPLEMENTED501Feature not configured (e.g. AI gateway)
INTERNAL_SERVER_ERROR500Unexpected server error

Versioning

The API is mounted at /api/v1. Any breaking change will land under a new version prefix; the old version keeps running until explicitly deprecated. The internal RPC endpoint at /api/rpc is unaffected and continues to power the dashboard.

Last updated on

On this page

Join hundreds of directory builders

Build your directory, launch, earn

Don't waste time on Stripe subscriptions or designing a pricing section. Get started today with our battle-tested stack and built-in monetization features.

Get Lifetime Access