Skip to main content
Reference · v1

API Reference

Base URL https://curateone.ai/api/v1 — JSON in, JSON out, bearer-key auth on every call.

Account

Who the key belongs to, and how many AI credits remain.

GET/me

Retrieve the account

Returns the account behind the presented API key, its plan, and the current billing period's credit usage. Use it as the canonical "is my key working?" probe.

Request
curl https://curateone.ai/api/v1/me \
  -H "Authorization: Bearer co_live_…"
Response
{
  "account": {
    "id": "acc_8f31…",
    "name": "Akino Studio",
    "email": "owner@example.com",
    "plan": "pro",
    "createdAt": 1750757400000
  },
  "usage": { "used": 14, "limit": 100, "remaining": 86, "bonusTokens": 25 }
}

Sites

Every website on the account — list them, inspect one, or generate a new one.

GET/sites

List sites

All sites on the account, newest first. `status` is draft, provisioning, or live; `url` is set once the site's subdomain is fully live (SSL + content checks passed).

Request
curl https://curateone.ai/api/v1/sites \
  -H "Authorization: Bearer co_live_…"
Response
{
  "sites": [
    {
      "id": "prj_ax92…",
      "name": "Billu Barber",
      "status": "live",
      "url": "https://billu-barber.curateone.ai",
      "customDomain": null,
      "pages": 5,
      "createdAt": 1751189000000,
      "updatedAt": 1752598000000
    }
  ]
}
POST/sites1 AI credit

Generate a site

Starts a full AI website generation as a background job and returns 202 with a job id. Poll GET /jobs/{jobId} until the job is terminal. Costs one AI generation credit, reserved up front and refunded automatically if the job fails or is cancelled.

Body parameters

businessNamerequiredstringThe business the site is for.
industryrequiredstringIndustry or category, e.g. "barber shop", "SaaS analytics".
audiencestringWho the site should speak to.
goalsstringWhat the site should achieve (bookings, signups, calls…).
personalitystringBrand personality cues, e.g. "premium, playful".
competitorsstringCompetitor names or URLs to differentiate from.
existingUrlstringAn existing website to draw context from.
Request
curl -X POST https://curateone.ai/api/v1/sites \
  -H "Authorization: Bearer co_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "businessName": "Billu Barber",
    "industry": "barber shop",
    "audience": "young professionals in Indiranagar",
    "goals": "walk-in bookings"
  }'
Response
{ "jobId": "job_k2f8…" }
GET/sites/{id}

Retrieve a site

One site by id. Returns 404 for sites that don't exist or belong to another account.

Request
curl https://curateone.ai/api/v1/sites/prj_ax92… \
  -H "Authorization: Bearer co_live_…"
Response
{
  "site": {
    "id": "prj_ax92…",
    "name": "Billu Barber",
    "status": "live",
    "url": "https://billu-barber.curateone.ai",
    "customDomain": null,
    "pages": 5,
    "createdAt": 1751189000000,
    "updatedAt": 1752598000000
  }
}

Generation jobs

Track a POST /sites generation from queued to live-editable.

GET/jobs/{id}

Poll a job

The job's current status: pending, running, completed, failed, or cancelled. Poll every 3–5 seconds. On completed, `siteId` is set — the generated site is then available via GET /sites/{siteId}. Failed and cancelled jobs refund their reserved credit automatically.

Request
curl https://curateone.ai/api/v1/jobs/job_k2f8… \
  -H "Authorization: Bearer co_live_…"
Response
{
  "job": {
    "id": "job_k2f8…",
    "status": "running",
    "progress": 62,
    "stage": "Composing pages",
    "siteId": null,
    "error": null
  }
}
DELETE/jobs/{id}

Cancel a job

Cancels a queued or running generation and refunds the reserved credit. Idempotent — cancelling a finished job returns its terminal state unchanged.

Request
curl -X DELETE https://curateone.ai/api/v1/jobs/job_k2f8… \
  -H "Authorization: Bearer co_live_…"
Response
{
  "job": { "id": "job_k2f8…", "status": "cancelled", "progress": 62, "stage": "Cancelled", "siteId": null, "error": null }
}

Leads

Form submissions captured on your live sites, with CRM status.

GET/sites/{id}/leads

List leads

The site's captured leads, newest first. Sync them into your own CRM, or use webhooks (see the Webhooks guide) for push instead of pull.

Query parameters

statusstringFilter: new, contacted, qualified, won, or lost.
limitnumberPage size, 1–200. Default 50.
skipnumberOffset for pagination. Default 0.
Request
curl "https://curateone.ai/api/v1/sites/prj_ax92…/leads?status=new&limit=50" \
  -H "Authorization: Bearer co_live_…"
Response
{
  "leads": [
    {
      "id": "led_77ab…",
      "name": "Priya S",
      "email": "priya@example.com",
      "phone": "+91 98…",
      "message": "Do you take Sunday appointments?",
      "status": "new",
      "source": "/contact",
      "createdAt": 1752600000000
    }
  ],
  "total": 1
}

Analytics

Cookieless first-party analytics for any site on the account.

GET/sites/{id}/analytics

Retrieve analytics

Traffic summary for the chosen range: pageviews, uniques, CTA clicks, form funnel, conversion, daily series, top pages/referrers, and privacy-safe device/country/language breakdowns.

Query parameters

rangestring7d, 30d (default), or 90d.
Request
curl "https://curateone.ai/api/v1/sites/prj_ax92…/analytics?range=30d" \
  -H "Authorization: Bearer co_live_…"
Response
{
  "analytics": {
    "range": 30,
    "pageviews": 1284,
    "uniques": 902,
    "ctaClicks": 187,
    "formViews": 240,
    "formSubmits": 41,
    "leads": 41,
    "conversion": 3.2,
    "series": [{ "day": "2026-07-15", "pageviews": 96 }],
    "topPaths": [{ "path": "/", "views": 810 }],
    "topReferrers": [{ "ref": "google.com", "visits": 322 }],
    "devices": [{ "device": "mobile", "views": 884 }],
    "topCountries": [{ "country": "IN", "views": 1030 }],
    "languages": [{ "lang": "en", "views": 1102 }],
    "sources": [{ "source": "organic", "views": 640 }]
  }
}