Skip to Content
Personas

Personas

A persona is a synthetic identity — a believable name, gender, date of birth, country, locale and address — with its own working email address. You use personas to sign up for and operate accounts on the sites you scrape, and to receive the verification codes those sites email, without ever creating or managing a real mailbox yourself.

Personas are billed per persona per month and are created in real time — there is no pool or waiting; you ask for N in a country and you get them instantly, each with an email address ready to receive mail.

How the email works

Every persona’s address lives on a domain the platform owns (e.g. clairemcguire@yourdomain.com). Those domains run a catch-all rule that forwards all their mail to one central mailbox the platform controls. When a site emails a persona, the message is forwarded to that mailbox, and the platform serves it back to you filtered to just that persona’s address.

You never hold a mailbox password. The platform reads the central mailbox server-side and returns only the messages addressed to your persona. This is the mediated inbox model — you get the mail and the codes, never a credential that could take over an account.

Generating personas

Open the Persona Profiles tab in the dashboard and click Generate Personas. Choose:

FieldMeaning
CountHow many to create (1–500).
CountryThe identity’s country — drives the name pool, locale, timezone and address. Each persona is created in the country you pick.
LabelOptional tag to help you find them later (e.g. a campaign name).

Each persona is created immediately with:

  • A locale-correct identity (name, gender, date of birth, address).
  • A unique, name-derived email address on one of the platform’s domains — for Claire McGuire you’ll get something like clairemcguire@…, claire.mcguire@… or c.mcguire@…, never random gibberish, and never a duplicate.

Click any persona in the list to open its detail panel: identity, email address (with copy), the inbox, and a free-form metadata editor where you can attach your own account fields (any key/value) — this is your data and is never read or used by the platform.

Inspecting a persona’s email

From a persona’s detail panel, click Open inbox to launch the full mailbox viewer. It is a proper two-pane mail client:

  • Message list (left) — newest first, paginated, so it scales to any volume.
  • Reader (right) — the selected message’s body, sender, date and any links.
  • Spam coverage — the viewer searches both the normal folder and Spam, so verification codes that get junked still show up (flagged with a spam badge).
  • Find code — type a regex (default \d{4,8}) and the viewer pulls the matching code out of the selected message with one-click copy.

Mail sent only via BCC carries no header trace of the persona’s address and can’t be attributed to a persona. Every normal To/Cc delivery is found.

API

The dashboard is built on a small REST API you can also call programmatically. All routes are under /api/v1, scoped to your organization, and authenticated with your platform (Auth0) access token:

Authorization: Bearer <access-token>

Generate

POST /api/v1/personas/batch Content-Type: application/json { "count": 5, "country": "MX", "label": "campaign-a" }

Returns 201 with the created personas:

{ "personas": [ { "id": "…", "first_name": "Claire", "last_name": "McGuire", "country": "MX", "email": { "address": "clairemcguire@…" }, "email_status": "ready", "status": "assigned" } ], "requested": 5, "created": 5 }

List & read

MethodPathPurpose
GET/api/v1/personasAll your personas.
GET/api/v1/personas/{id}One persona (identity + email address).
PATCH/api/v1/personas/{id}Update label and/or attributes (your metadata).
DELETE/api/v1/personas/{id}Retire it (stops next-cycle billing).

Inbox

GET /api/v1/personas/{id}/inbox?limit=25&offset=0

Returns a page of messages, newest first, across the normal and spam folders:

{ "messages": [ { "uid": 1837, "folder": "inbox", "from": "no-reply@site.com", "subject": "Your code", "date": "2026-07-01T04:11:32Z", "snippet": "Your code is 483920 …", "text_body": "…", "links": ["https://…"] } ], "total": 3, "limit": 25, "offset": 0, "has_more": false }

Latest message + code extraction

The one call you’ll use most from automation — fetch the newest matching message and pull a code out of it in one shot:

GET /api/v1/personas/{id}/messages/latest?from=site.com&extract=\d{6}
  • from — optional, case-insensitive substring match on the sender.
  • extract — optional regex; the first capture group (or full match) is returned as extracted. The raw message is always returned alongside it.
{ "found": true, "message": { "subject": "Your code", "from": "no-reply@site.com", "text_body": "Your code is 483920", "extracted": "483920" } }

Inbox reads are rate-limited per persona and every read is audit-logged. The platform warrants faithful delivery of your persona’s mail; extraction is your regex and is best-effort — the raw message is always returned so you can parse it yourself.

Using personas from crawlers

Spiders don’t use your dashboard login. They call a small crawler API under /api/v1/crawler, authenticated with the short-lived, org-scoped job token the platform already injects into every job as BROWSER_TOKEN — the same token your browsers use. Nothing new to configure:

  • ISBACKEND_INTERNAL_URL — the API base URL (already injected).
  • BROWSER_TOKEN — the org-scoped job token (already injected).

The token carries your org, so a spider only ever sees its own org’s personas and inboxes.

The example below is a complete, self-contained spider pattern — list personas, paginate inboxes, read a full email, and extract a code — using only the two injected environment variables and the standard library.

List your personas

GET {ISBACKEND_INTERNAL_URL}/api/v1/crawler/personas Authorization: Bearer {BROWSER_TOKEN}

Returns your org’s active personas, each with identity + email address:

{ "count": 12, "personas": [ { "id": "…", "first_name": "Claire", "last_name": "McGuire", "country": "MX", "email": { "address": "clairemcguire@…" } } ] }

Read a persona’s inbox (paginated, full emails)

GET {ISBACKEND_INTERNAL_URL}/api/v1/crawler/personas/{id}/inbox?limit=25&offset=0 Authorization: Bearer {BROWSER_TOKEN}

Each message in the page carries the complete emailtext_body, html_body, links and snippet, plus a folder of inbox or spam — not just metadata. Page with limit/offset; the response includes total and has_more.

Read the newest email / extract a code

GET {ISBACKEND_INTERNAL_URL}/api/v1/crawler/personas/{id}/messages/latest?from=site.com&extract=\d{6} Authorization: Bearer {BROWSER_TOKEN}

Returns the newest matching message in full. extract is optional — with it you also get extracted (the code); without it you still get the whole body, so you can read or validate the entire email yourself.

Example — inside a spider (urllib, no extra deps)

import json, os, urllib.parse, urllib.request BASE = os.environ["ISBACKEND_INTERNAL_URL"].rstrip("/") TOKEN = os.environ["BROWSER_TOKEN"] def api_get(path, params=None): url = BASE + path + (("?" + urllib.parse.urlencode(params)) if params else "") req = urllib.request.Request(url, headers={"Authorization": f"Bearer {TOKEN}"}) with urllib.request.urlopen(req, timeout=30) as r: return json.load(r) # 1. Pick a persona. persona = api_get("/api/v1/crawler/personas")["personas"][0] pid, email = persona["id"], persona["email"]["address"] # 2. Read its inbox — every message includes the full body. page = api_get(f"/api/v1/crawler/personas/{pid}/inbox", {"limit": 25, "offset": 0}) for m in page["messages"]: print(m["folder"], m["from"], m["subject"], len(m.get("text_body") or "")) # 3a. Read the newest email IN FULL (no extraction). full = api_get(f"/api/v1/crawler/personas/{pid}/messages/latest")["message"] print(full["text_body"]) # the complete email body print(full.get("links", [])) # and its links # 3b. Or pull a verification code out of the newest message. res = api_get(f"/api/v1/crawler/personas/{pid}/messages/latest", {"extract": r"\d{6}"}) code = (res.get("message") or {}).get("extracted")

The whole loop: generate personas (dashboard or API) → your spider lists them and reads the identity + email → signs the persona up on the target site → reads the inbox (full email) or polls messages/latest for the code → continues. No mailbox to manage, no credentials to hold.

Optional — personas in your addon database

If your project has the Postgres addon, the platform also projects your personas into your addon database as a read-only personas table, kept in sync automatically. So identity + email is a plain SQL query over the DSN your spiders already use — no HTTP:

import os, psycopg2 # your addon DSN is injected as an env var conn = psycopg2.connect(os.environ["POSTGRES_URL"]) # your injected addon DSN cur = conn.cursor() cur.execute(""" SELECT id, first_name, last_name, email_address, country FROM personas WHERE email_status = 'ready' AND country = %s ORDER BY updated_at DESC LIMIT 1 """, ("MX",)) persona_id, first, last, email, country = cur.fetchone()

Columns: id, first_name, last_name, gender, date_of_birth, country, locale, timezone, address (jsonb), email_address, status, email_status, attributes (jsonb), updated_at. Retired personas are removed. The table never contains a mailbox credential — there isn’t one. Use persona_id with the inbox API above to read mail; a live mailbox read stays behind the API (it’s not static data).

Last updated on