Sign up a customer

Lovelio's signup endpoint is public - no auth, no demo, no sales call. You give it an email. It gives you back an account on a 14-day free trial, no card needed, plus a trial API key that can read immediately; writes unlock when the customer verifies their email.

Endpoint

POST /api/v1/accounts/signup

Choose the region before you sign up. The workspace is created in the region of the domain you call - us.lovelio.ai (Americas and rest of world), eu.lovelio.ai (UK, Ireland, Europe), or anz.lovelio.ai (Australia, New Zealand) - and it lives there permanently, along with the API key you get back. Pick the region where the agency's data should reside, then call signup once. Never try several regional hosts: each region is its own database, and a second call on another region is answered with the host where the account already lives (status: "exists_in_other_region", plus region and api_base_url) and no key.

Body: { "email": "founder@acme.com", "source": "claude-agent" }

Response (HTTP 202):

{
  "success": true,
  "data": {
    "account_id": "acc_01HXXX...",
    "status": "pending_verification",
    "trial_api_key": "sk_trial_abc123...",
    "email_verified": false,
    "message": "Your 14-day free trial has started, no card needed. Verify your email (check your inbox) to create and change data. Choose a plan at card_url any time.",
    "trial_ends_at": "2026-10-26T09:00:00.000Z",
    "trial_status": "active",
    "card_url": "https://us.lovelio.ai/settings/billing",
    "region": "us",
    "api_base_url": "https://us.lovelio.ai/api/v1",
    "enrichment_task_id": null
  },
  "meta": { "request_id": "req_abc123def456" },
  "error": null
}

The trial_api_key is returned once. Store it; you cannot retrieve it later. If lost, an account admin can mint a new key via POST /api/v1/accounts/{id}/api-keys.

curl

curl -X POST https://us.lovelio.ai/api/v1/accounts/signup \
  -H "Content-Type: application/json" \
  -d '{"email": "founder@acme.com", "source": "claude-agent"}'

JavaScript

const res = await fetch('https://us.lovelio.ai/api/v1/accounts/signup', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ email: 'founder@acme.com', source: 'claude-agent' }),
});
const { data } = await res.json();
const apiKey = data.trial_api_key;
// Store apiKey. All subsequent calls use: Authorization: Bearer <apiKey>

Python

import requests

r = requests.post(
    'https://us.lovelio.ai/api/v1/accounts/signup',
    json={'email': 'founder@acme.com', 'source': 'claude-agent'},
    timeout=30,
)
r.raise_for_status()
api_key = r.json()['data']['trial_api_key']
# Store api_key. Use it as Authorization: Bearer <api_key> on every subsequent call.

What happens next

  1. A verification email goes to the address. Until the customer clicks it, the trial key can read but not create or change data; clicking it unlocks writes. The trial lasts 14 days (trial_ends_at), and so does the trial key. An admin chooses a plan at card_url any time.
  2. One free trial per work email domain. A domain that has already had one gets trial_ends_at: null and trial_status: "domain_already_used", and the key answers 402 until an admin chooses a plan at card_url.
  3. Lovelio crawls the domain, fetches branding colours + logo, and sets a sensible timezone.
  4. An account.enriched webhook fires when enrichment finishes (about 10-30 seconds). Subscribe via POST /api/v1/webhooks if you want push instead of poll.

Duplicate handling

If the email already has an account, in this region or any other, the endpoint returns HTTP 202 with the existing account_id and a message telling the caller to check email for the verification link. It does not return a new API key. When the account lives in another region the response carries status: "exists_in_other_region", region and api_base_url: use that host from then on. Build your flow so a duplicate signup is a no-op, not an error.

If another account in this region already claims the same email domain (e.g. someone at acme.com signed up before), the endpoint returns HTTP 409 with error.code = "CONFLICT" and a human-readable reason. Bounce the user to that account's admin or pick a different domain.

Verifying the email programmatically

The verification link in the email points to /auth/verify-email?token=.... For a fully headless onboarding flow, you cannot read the email on behalf of the user. Two options:

  • Let the human click the link themselves. The trial key can read in the meantime; writes wait for the click.
  • Use the invite flow instead: have an existing admin call POST /api/v1/accounts/{id}/users to create a member with a known password. That skips email verification entirely but requires you to already be signed in.

Rate limits

The signup endpoint is IP-rate-limited: 3 signups per hour and 5 per day per IP. If you hit 429, wait for the Retry-After header and try again.

Hand this to your agent

Sign up a new Lovelio account for founder@acme.com, store the trial
API key in an env var called LOVELIO_API_KEY, and print the account_id.