Waveform Apps Developer API
A small public JSON API and machine-readable resources for agents and integrations.
Overview
The Waveform Apps API is a small public JSON API for reading what we build, what it costs and what we have shipped, and for sending us a message. It exists so AI agents and integrations can act for a user without scraping the site.
- Base URL:
- Specification: /openapi.json (OpenAPI 3.1 with operationIds and typed request and response schemas)
- Agent guide: /llms.txt
- Machine-readable documents: /pricing.md, /llms-full.txt, /.well-known/ard.json (also at /.well-known/ai-catalog.json), /sitemap.xml and /.well-known/security.txt
- Markdown pages: every page returns Markdown when requested with
Accept: text/markdown, or by appending.mdto the page URL (for examplehttps://www.waveformapps.com/about.md). - Cross-origin: every response carries
Access-Control-Allow-Origin: *, so browser-based callers can read the API from any origin.OPTIONSpreflights are free and never use up rate limit. - HEAD: GET endpoints answer
HEADwith the same status and headers and no body, so you can check availability without downloading anything. - Caching: the catalog GETs carry an
ETagandCache-Control: public, max-age=300. Send the ETag back inIf-None-Match; a match answers304with no body. The machine documents this site serves itself (/openapi.json,/.well-known/ard.json,/pricing.md) revalidate the same way.
Authentication
None. Every endpoint is public and anonymous. Rate limits apply per client IP address (IPv6: per /64 prefix), and the contact endpoint sends one email per successful call, so treat it as non-idempotent.
Endpoints
GET /api/servicesList the services Waveform Apps offers (listServices). Returns every service category with a one-line description. Read-only, takes no parameters and changes only when the site is redeployed.HEAD /api/servicesCheck the services list without a response body (headServices). Identical to listServices (RFC 9110 section 9.3.2): same status and headers, no response content. Useful for availability checks and cache warm-ups.GET /api/pricingList fixed-price project options (listPricingOptions). Returns the published project packages with price, timeline and what is included. Every option carries both the display string exactly as shown on the pricing page (price) and structured fields:currency+priceValuegive the numeric figure, andpriceIsFrommarks a starting point rather than a final price. Every project includes 30 days of free maintenance. After that, a care plan is $99 a month. Cancel any month. Read-only and takes no parameters.HEAD /api/pricingCheck the pricing list without a response body (headPricing). Identical to listPricingOptions (RFC 9110 section 9.3.2): same status and headers, no response content.GET /api/workList the projects the studio has shipped (listProjects). Returns shipped projects with a one-paragraph summary, the stack behind each where published and a link to the live site — the same catalog as the work page. Read-only and takes no parameters; it changes only when the site is redeployed.HEAD /api/workCheck the project list without a response body (headProjects). Identical to listProjects (RFC 9110 section 9.3.2): same status and headers, no response content.GET /api/faqList the frequently asked questions and their published answers (listFaq). Returns the homepage FAQ verbatim: pricing, timelines, maintenance and how to start. Read-only and takes no parameters; it changes only when the site is redeployed. Prefer this over scraping the page for the same answers.HEAD /api/faqCheck the FAQ list without a response body (headFaq). Identical to listFaq (RFC 9110 section 9.3.2): same status and headers, no response content.GET /api/processList the steps of a Waveform Apps project (listProcessSteps). Returns the 4-step engagement process — call, design, build, launch and care — with what happens in each. Read-only and takes no parameters; it changes only when the site is redeployed.HEAD /api/processCheck the process list without a response body (headProcessSteps). Identical to listProcessSteps (RFC 9110 section 9.3.2): same status and headers, no response content.POST /api/contactSend a project enquiry to Waveform Apps (sendContactMessage). Delivers a message to the Waveform Apps team by email. Use it when a user wants to hire Waveform Apps, ask for a quote, or start a project conversation. Send the user's real name and a reachable email address; the team replies to that address within one business day. Not idempotent: every successful call sends one message, so do not retry a 200.
Rate limits
10 requests per 60 seconds per client IP address (IPv6: per /64 prefix) across all /api/ endpoints, using the IETF RateLimit header fields draft. Every API response carries the policy; a 429 response also carries the remaining quota and a Retry-After value in seconds.
RateLimit-Policy: "api";q=10;w=60
HTTP/1.1 429 Too Many Requests
RateLimit-Policy: "api";q=10;w=60
RateLimit: "api";r=0;t=60
Retry-After: 60Errors
Errors use RFC 9457 problem details with the content type application/problem+json. Every error has type, title, status, detail, a stable code, and a hint that says how to recover. Validation errors add an errors array of field and message pairs.
{
"type": "https://www.waveformapps.com/api-docs#errors",
"title": "Bad Request",
"status": 400,
"detail": "One or more fields are invalid.",
"code": "validation_failed",
"hint": "Fix the fields listed in `errors` and resend.",
"errors": [
{
"field": "email",
"message": "Valid email is required"
}
]
}not_found: No endpoint at that path (404).method_not_allowed: Wrong HTTP method; the Allow header lists the supported ones (405).unsupported_media_type: The POST body was not sent as application/json (415).payload_too_large: The POST body is over 16 KiB (413).invalid_json: The POST body could not be parsed as JSON (400).validation_failed: A field is missing or invalid; errors lists each field (400).rate_limited: Over the rate limit; wait Retry-After seconds and retry (429).email_unavailable: Email delivery failed; retry later or email hello@waveformapps.com (503).internal_error: The server hit an unexpected fault; retry, and report it if it keeps failing (500).
Examples
curl https://www.waveformapps.com/api/services
curl https://www.waveformapps.com/api/pricing
curl https://www.waveformapps.com/api/work
curl https://www.waveformapps.com/api/faq
curl https://www.waveformapps.com/api/process
curl -X POST https://www.waveformapps.com/api/contact \
-H "Content-Type: application/json" \
-d '{
"name": "Ada Lovelace",
"email": "ada@example.com",
"message": "We need a booking website for a two-location clinic."
}'
curl -H "Accept: text/markdown" https://www.waveformapps.com/about
curl https://www.waveformapps.com/about.md