Skip to main content
Test mode gives you a key that answers every endpoint with fictional data, at the speed the real endpoint runs, showing the price the real call would have cost — and charges nothing. There is no separate host and no separate base URL. https://api.generect.com serves both modes and the key decides which one you get. Moving an integration from test to live is a change of credential, nothing else.

Get a test key

Create one over the API with the key you already have:
The response carries the new key. Test keys start with test_, so you can tell one from a live key at a glance, in a log line or in a support ticket.
Picking Test when creating a key in the app is rolling out. Until it reaches your account, use the call above.

Your first test call

Identical to the live call in every respect but the key. The response carries a header:
Check that header in your integration tests. It is the one signal that is present on every endpoint, including the older /api/linkedin/* ones that have no meta envelope.

What is real, and what is not

Real: validation

An unknown filter is still a 400, with the same message. A sandbox that accepted anything would teach you that a broken payload is fine.

Real: response shapes

Fixtures are generated through the same serializers that build live responses, so every field a live row has, a test row has.

Real: timings

Each endpoint waits about as long as it really takes, drawn from production percentiles. Write your timeouts against these.

Real: prices

meta.amount_charged is computed by the live pricing code against your own tier. Nothing is debited.

Not real: the data

Fictional people at fictional companies. Nothing is fetched from LinkedIn or any provider.

Not real: the ledger

No transaction is written and your balance never moves. Test calls do not appear in billing history.

Recognising a fixture

Test data is meant to be unmistakable:
One exception worth knowing. The email finder builds its address on the domain you asked for, because that is what the live endpoint does and your integration needs to check it. Ask for ada.testwell at microsoft.com and you get ada.testwell@microsoft.com — a synthetic address that looks real. It is not deliverable, and the row is marked "source": "test_mode". Never feed test-mode output into a sending pipeline.

Magic inputs: reproduce a failure on demand

The paths worth rehearsing are the ones you cannot ask production for. You cannot request a 402 without actually running out of money, so test mode gives you reserved values that force an outcome. Put one in any identity field — an email, a LinkedIn URL, a company name: The fragment has to be a whole segment, so slowik@example.com is an ordinary address and does not trigger anything.

The header form

Searches have no single subject to hide a magic value in, so the same behaviours are available as a request header:
Accepted values: not_found, insufficient_funds, rate_limited, upstream_error, slow, and latency=<seconds> to force a specific delay. The header is ignored by live keys.

Determinism

The same request body returns the same fictional people every time. You can assert on a name or a count in your own test suite and it will keep passing, and a retry after a timeout returns what the first attempt would have. Change the query and you get different people.

Page size

Test mode honours the limit_by you send, up to a ceiling on how many rows it will fabricate for one response. Every fixture row is generated through the same serializers that build live responses, so a page has a real cost. Ask for more than the ceiling and you get the ceiling, not an error, and results_count still reports the full population so your pagination logic has something to page through. Assert <= on the page size rather than == and your tests keep passing when the ceiling moves. Nested criteria are read where the live endpoint reads them. For company-leads, the page comes from lead_search_criteria.limit_by, not from a top-level limit_by.

Bulk jobs

Bulk endpoints behave like bulk endpoints: the submit returns pending with a job_id, the first poll returns processing, and the second returns completed with the rows. That is deliberate — a job that is already finished on the first poll would let you ship a client that never handles the waiting state.

Coverage

Supported: search (leads, companies, company-leads, and their counts), enrich (leads and companies, database and realtime, single and bulk), email finder and validation, phone finder, preview, and the legacy /api/linkedin/* endpoints. /api/v1/accounts/* works normally with a test key and returns your real account — that is what you want when you are checking a balance or a tier. Not yet supported: the datahub gateway (/api/v1/data/…) and webhook management. A test key on an endpoint without fixtures returns:
That refusal is deliberate. An endpoint we have not covered will not quietly answer a test key with real data.

Going live

Swap the key. Nothing else changes — same URL, same payloads, same response shapes.
1

Check the header is gone

Assert X-Generect-Mode is absent in production. If it says test, you shipped the wrong key.
2

Fund the account

See Pay as you go. Test mode reports prices but never debits, so a live key is the first thing that will meet an empty balance.
3

Keep the test key

It costs nothing to keep and it is the cheapest way to rehearse the next change.