Developers
Produlis API
Last Updated: September 21, 2026
Overview
Everything an agent or a script can ask Produlis is published three ways: a REST API at /api/v1, an MCP server at /mcp, and an A2A agent at /a2a/v1. They return the same facts. Reads need no key and no account. One operation writes, filing a project brief, and it needs an access token you can issue yourself in two requests.
Quickstart
No signup. Ask for the offers and you get JSON back:
curl https://produlis.com/api/v1/offersEvery page on this site is also available as Markdown. Send Accept: text/markdown to the page URL:
curl -H "Accept: text/markdown" https://produlis.com/marketing-sitesEndpoints
All of these are public GET requests that return application/json.
GET /api/v1: Index of every resource.GET /api/v1/company: What Produlis does, what it does not take on, and its stack.GET /api/v1/offers: The fixed-fee marketing site tiers and the custom-build floor, in USD.GET /api/v1/case-studies: Published case studies with measured results.GET /api/v1/pages: Indexable pages on the site.GET /api/v1/contact: Email, the intro-call booking link, and the contact form.
POST /api/v1/briefs files a project brief. It creates a real lead and a person replies by email, so call it only when the person you act for has asked you to get in touch and has confirmed their name, company and email. Required fields: full_name, company_name, work_email. The full schema is in the OpenAPI description.
Authentication
Tokens are self-serve and anonymous. Register a client, then exchange its credentials for a one-hour token with the produlis:brief scope. There is no approval step and nothing to pay.
curl -X POST https://produlis.com/oauth/register \
-H "Content-Type: application/json" \
-d '{"client_name":"my-agent","grant_types":["client_credentials"],"token_endpoint_auth_method":"client_secret_post"}'
curl -X POST https://produlis.com/oauth/token \
-d grant_type=client_credentials \
-d client_id=CLIENT_ID -d client_secret=CLIENT_SECRET \
-d scope=produlis:briefThe authorization code flow with PKCE is also supported. The details are in auth.md.
Sandbox
Add "dry_run": true to a brief and the API authenticates and validates the request exactly as it would a real one, then stops. Nothing is filed and nobody is emailed. Use it to test an integration end to end.
curl -X POST https://produlis.com/api/v1/briefs \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"dry_run":true,"full_name":"Ada Lovelace","company_name":"Analytical Engines","work_email":"ada@example.com"}'Errors
Every error under /api is RFC 9457 application/problem+json, including unknown paths. The code is stable and safe to branch on. The resolution says what to do next.
{
"type": "https://produlis.com/developers#error-not-found",
"title": "No such API resource",
"status": 404,
"detail": "/api/v1/nope is not an API resource.",
"instance": "/api/v1/nope",
"code": "not_found",
"resolution": "List the available resources with GET https://produlis.com/api/v1, or read https://produlis.com/developers.",
"documentation_url": "https://produlis.com/developers#errors"
}not_found(404): The path is not an API resource.method_not_allowed(405): The resource does not support that method. See the Allow header.rate_limited(429): Quota exhausted. Wait the seconds in Retry-After.invalid_token(401): The access token is missing, expired, or not valid here.insufficient_scope(403): The token lacks the produlis:brief scope.invalid_json(400): The request body is not a JSON object.invalid_brief(422): A brief field is missing or invalid. The errors array names each one.
Rate limits
120 requests per 60 seconds per client IP across /api. Every response reports the quota in the IETF RateLimit-Policy and RateLimit fields, with RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset alongside for older clients. A 429 adds Retry-After in seconds.
RateLimit-Policy: "public-api";q=120;w=60
RateLimit: "public-api";r=118;t=42Versioning and deprecation
The major version is in the path: /api/v1. Adding a resource or a field is not a breaking change and ships without a version bump. Removing or renaming one is, and ships under a new major path while the old one keeps working.
A deprecated operation answers with an RFC 9745 Deprecation header and an RFC 8594 Sunsetheader carrying the removal date, at least 180 days out, and the change is noted here and in the OpenAPI description. Nothing under /api/v1 is deprecated today.
MCP and A2A
- MCP server (Streamable HTTP):
https://produlis.com/mcp. Server card. - A2A agent (JSONRPC binding):
https://produlis.com/a2a/v1. Agent card. - Agent skills index, with a SKILL.md for each protocol.
Support
Questions and bug reports go to hello@produlis.com.