Skip to main content

API Reference

Endpoints powering refrase.cc/enhance and the browser extension. All endpoints accept and return JSON.

Web app (same-origin): https://refrase.cc/api
Adapter Lambda (direct): https://dtxuqh4c4bzb7jo3tnfbftvto40prutn.lambda-url.us-east-1.on.aws/

A dedicated public REST API (api.refrase.cc) with API keys is on the roadmap. For now the web/extension call the Adapter Lambda directly with a Cognito Bearer token.

POST /api/demo-enhance

Public, unauthenticated demo endpoint. Rate-limited to 3 requests per IP per UTC day via Upstash Redis. Same enhancer used by the authenticated flow.

Request body

{
  "prompt": "write me an email about a project delay",
  "model": "claude-sonnet",
  "task": "general"           // optional: code | writing | analysis | extraction | general
}

Response (200)

{
  "enhanced_prompt": "<role>You are a professional communicator...</role>\n<instructions>...",
  "changes": [
    { "what": "Wrapped instructions in XML tags", "why": "Claude follows tagged sections more reliably" },
    { "what": "Specified tone and length", "why": "Surfaces an implicit constraint the user didn't state" }
  ],
  "latency_ms": 4820,
  "model": "claude-sonnet",
  "model_name": "Claude Sonnet 4.6"
}

Returns 429 when the per-IP daily limit is exceeded.

POST <adapter-lambda-url>/

Authenticated enhance endpoint (Quick or Guided mode). Used by the web app and the browser extension. Authenticate with Authorization: Bearer <cognito-id-token>.

Quick mode request

{
  "mode": "quick",
  "prompt": "clean up this code",
  "model": "claude-sonnet",
  "task": "code"
}

Guided mode requests

// Start a guided session — returns the first clarifying question
{
  "mode": "guided_start",
  "prompt": "I want to draft something for my team",
  "model": "claude-sonnet"
}

// Answer a question — returns the next question OR the final enhanced prompt
{
  "mode": "guided_answer",
  "session_id": "...",
  "answer": "Engineering team, internal Slack post, somewhat informal"
}

// Generate now — short-circuit any pending questions and return the result
{
  "mode": "guided_answer",
  "session_id": "...",
  "generate_now": true
}

Error responses

  • 402 — no active subscription/trial ({ "reason": "no_subscription" | "trial_expired", "upgrade_url": "https://refrase.cc/pricing" })
  • 429 — daily Quick limit (50) or monthly Guided limit (30) reached. Returns resets_at ISO timestamp.
  • 503 — model throttled by Bedrock. Retry after a moment.

Web app endpoints

These run on Next.js routes at refrase.cc/api/*. They all require Authorization: Bearer <cognito-id-token> unless noted.

GET /api/dashboard

Returns the signed-in user's subscription status, quota counters, last 10 enhancements (recent activity), and account metadata.

GET /api/history?cursor=&limit=20

Paginated history of the user's enhancements (90-day retention).

POST /api/share

Create a public shared link from an enhancement. Returns { "id": "...", "url": "/s/<id>" }. Rate-limited per IP. No auth required for the read side at /s/[id].

POST /api/checkout

Creates a Stripe Checkout session for the 7-day trial → $9/mo subscription. Returns the redirect URL.

POST /api/portal

Returns a Stripe billing portal URL for the signed-in user.

POST /api/webhooks/stripe

Stripe webhook receiver. Handles checkout.session.completed, customer.subscription.updated, customer.subscription.trial_will_end, customer.subscription.deleted, invoice.paid, invoice.payment_failed.

SDKs

The published refrase packages on npm and PyPI are at v0.x — they apply deterministic prompt-pattern adaptations locally and are useful for offline / no-API-key workflows. The v0.3 product (the LLM-powered enhancer used by the web app and extension) is not yet available through the SDK; v1.0 of the packages will be rewritten as official API clients.

For now, the easiest way to call the v0.3 enhancer programmatically is the public demo endpoint above (3/IP/day) or to sign in and use the authenticated Adapter Lambda directly with a Cognito Bearer token.

Calling /api/demo-enhance

typescript
python