The Twins Proxy API
Everything the dashboard does — creating sites, provisioning masking domains, verifying DNS access, managing certificates — is available over a versioned REST interface. Requests and responses are JSON; the base path is /v1.
# List your domains
curl https://your-host/v1/domains \
-H "Authorization: Bearer twp_live_…"
Authentication
Two credential types go in the Authorization: Bearer header: session tokens from login, and long-lived scoped API keys. Secrets are returned once on creation; the server stores only SHA-256 hashes.
Sites
A site is a reusable landing-page origin — a name and an HTTPS URL. Any number of masked domains may route to the same site.
curl -X POST /v1/sites \
-H "Authorization: Bearer $TOKEN" \
-d '{"name":"Acme landing","origin_url":"https://landing.acmemail.io"}'
Domains
Creating a domain starts the provisioning pipeline. With dns_method: "cloudflare" (default) validation records are written automatically; with dns_method: "manual" the API returns the TXT records to create at any DNS provider, and issuance starts once they are visible. Certificates cover the hostname and *.hostname. The proxy deploys once an origin is attached; the domain becomes active only after the edge answers HTTP 200.
curl -X POST /v1/domains \
-H "Authorization: Bearer $TOKEN" \
-d '{"dns_connection_id":"…","dns_zone_id":"…",
"domain":"go.acmemail.io"}'
DNS connections
A connection is a labeled Cloudflare account token (Zone Read + DNS Edit), encrypted at rest with AES-256-GCM. Zones are discovered automatically; write access is proven with a temporary TXT record removed after the check.
Certificates
Production certificates renew on a schedule well before expiry. Revocation is permanent and immediately suspends the domain’s proxy — prefer domain suspension for temporary downtime.
API keys
Scopes follow resource:access — e.g. sites:read, domains:write. Grant the smallest set that works, and prefer an expiration.
Billing
Plans: Free (1 domain), Basic (10 domains, $10/mo), Pro (25 domains, $20/mo), each with monthly bandwidth and request allowances. The domain limit is enforced at creation with HTTP 402.
Errors
Failures return a conventional HTTP status and a JSON body with a stable machine-readable code and a human-readable message.
{ "error": { "code": "dns_write_not_verified",
"message": "Verify DNS write access for the selected zone first" } }