Skip to Content
API ReferenceAuthentication

Authentication

The base URL is https://api.vdclip.com and the REST surface lives under /v1/*. There are two ways to authenticate:

🔑

API key

Authorization: Bearer vdck_... on every /v1 request. Server-to-server only.

🤖

OAuth 2.1

Authorization: Bearer <JWT> for MCP servers, AI agents, and integrations acting for a user.

API keys

Send your API key in the Authorization header as a Bearer token on every /v1 request. Keys are prefixed with vdck_.

curl https://api.vdclip.com/v1/account \ -H "Authorization: Bearer vdck_your_key_here"

A successful response returns the resource directly:

{ "id": "acc_...", "plan": "pro", "credits": 120 }
i
Never expose your API key in a browser

The API is server-to-server only. It has no CORS, so browser requests are rejected with ORIGIN_REJECTED. Treat vdck_... keys like a password: keep them in server environment variables or a secret manager, never in front-end code, mobile apps, or anything a user can inspect. If a key is exposed, rotate it immediately.

Pagination

List endpoints use cursor pagination. Pass a limit, then pass the returned cursor to fetch the next page. Defaults and maximums vary per endpoint and live in the OpenAPI spec.

curl "https://api.vdclip.com/v1/projects?limit=20" \ -H "Authorization: Bearer vdck_your_key_here"

Scopes

Each scope follows the pattern vdclip:<resource>:<action>. A request without the scope its endpoint needs is rejected with MISSING_SCOPE. OAuth clients request the same scopes. The full catalog is in MCP Servers, and each endpoint page lists the scope it requires.

vdclip:render:execute and vdclip:social:publish are plan-gated: they only work on plans that include them, even when the key carries the scope. Render endpoints also consume credits, returning INSUFFICIENT_CREDITS when you run out. See the pricing page  for what each plan includes.

Error responses

All /v1 errors use an errors array, with a machine-readable code and a human-readable description:

{ "errors": [ { "code": "MISSING_SCOPE", "description": "This credential is not authorized for vdclip:render:execute." } ] }
CodeMeaning
INVALID_API_KEYThe Authorization header is missing, malformed, or unknown
MISSING_SCOPEThe key lacks the scope required by this endpoint
INSUFFICIENT_CREDITSNot enough credits to complete the operation
RATE_LIMITEDToo many requests (see rate limiting below)
UPSTREAM_ERRORA downstream service failed
VALIDATION_ERRORThe request body or query failed validation
INVALID_JSONThe request body is not valid JSON
NOT_FOUNDThe requested resource does not exist
ORIGIN_REJECTEDThe request came from a disallowed origin (browser)

Include the X-Request-ID response header from a failing response when you contact contact@vdclip.com.

Rate limiting

When you exceed the rate limit, the API responds with HTTP 429 and a Retry-After header (in seconds). Wait at least that long, and use exponential backoff for repeated 429 responses.

HTTP/1.1 429 Too Many Requests Retry-After: 30

OAuth 2.1 for user-delegated clients

For MCP servers, AI agents, and third-party integrations that act on behalf of a user, VDClip runs an OAuth 2.1 Authorization Server. These clients send Authorization: Bearer <JWT> instead of an API key.

  • The issuer is https://api.vdclip.com. OAuth endpoints live under /oauth2/*, discovery under /.well-known/*.
  • Access tokens are JWTs (at+jwt, ES256).
  • These endpoints use RFC-standard bodies, not the /v1 envelope.
  • They use the same vdclip:<resource>:<action> scopes, with the same plan-gating.

Clients start at discovery (RFC 8414), which advertises the issuer, the authorize/token/revoke endpoints, the supported scopes, and the JWKS URI for verifying token signatures:

curl https://api.vdclip.com/.well-known/oauth-authorization-server

With an access token, a client calls the same /v1 endpoints with the same Bearer header:

curl https://api.vdclip.com/v1/projects \ -H "Authorization: Bearer <JWT>"

See OAuth 2.1 for the full flow.

Tips & Best Practices

Keep keys on the server

Store vdck_ keys in environment variables or a secret manager. A key in browser code cannot work and only risks exposure.

Scope keys narrowly

Grant only the scopes an integration needs. A read-only integration should never hold write or render:execute scopes.

Handle 429 with backoff

Respect the Retry-After header and use exponential backoff so a burst of requests does not keep tripping the rate limiter.

Log request headers

Store X-Request-ID and X-Trace-ID from responses so you can reference exact requests when you reach out to support.

Use OAuth only for user-delegated clients

Use the OAuth 2.1 Bearer flow when a client acts for a user. For your own backend, an API key is simpler.

Frequently Asked Questions

Last updated on