Build a demo tenant

This guide shows how to turn a user request into a demo tenant in your product.

For a standard Fictix customer, create the company in the Fictix Console and connect it with a project runtime key.

The programmatic control-plane flow below is for approved backend-to-backend integrations. Configure the Fictix-supplied FICTIX_ADMIN_API_KEY as X-Admin-Key server-side. The signed-in Console uses its own managed WorkOS bearer session for Console actions; that session is not a customer credential to copy or forward. Never use an email/password login, copy a browser session token, or put the admin key in frontend code.

Goal

Given a user selection like:

Create a mid-market logistics company with QBO, Gusto, HubSpot, and Asana data.

Your system should:

  1. create a Fictix demo job
  2. wait for readiness
  3. fetch entity data
  4. map it into your product schema
  5. store lineage
  6. show the user a ready demo tenant
Browser
  -> your backend
    -> Fictix approved server-to-server demo-jobs API
    -> your loader workers
    -> your database
  -> browser sees ready tenant

Do not call Fictix with management credentials directly from the browser.

Step 1: Build the create request

Map your UI form into the Fictix create payload:

{
  "company": {
    "name": "Acme Logistics",
    "domain": "acme-logistics.example",
    "industry": "Logistics",
    "employee_count": 120,
    "annual_revenue": 24000000,
    "customer_accounts": 1500,
    "selected_services": ["qbo", "gusto", "hubspot", "asana"]
  },
  "generation": {
    "employees": 120,
    "months_of_history": 24,
    "quality_preset": "realistic"
  },
  "simulation": {
    "seed": 42
  }
}

Use .example domains for clearly synthetic companies.

ASC healthcare tenant

For a synthetic ambulatory surgery center, use company.industry rather than company.archetype:

{
  "company": {
    "name": "Lakeside Surgery Center",
    "domain": "lakeside-surgery.example",
    "industry": "asc_surgical"
  }
}

The resulting company adds synthetic clinical entities. It contains no real patient data; see Healthcare / ASC Data before loading or evaluating it.

Step 2: Create job with idempotency

Generate an idempotency key from your internal request id:

tenant-create-{tenant_request_id}

Then call:

POST/api/v1/demo-jobs
POST /api/v1/demo-jobs

Store:

  • Fictix job id
  • original request
  • returned company metadata
  • status
  • links
  • runtime ids

Step 3: Wait for readiness

Poll:

GET/api/v1/demo-jobs/{job_id}/status
GET /api/v1/demo-jobs/{job_id}/status

Treat status=ready as generation complete, then inspect quality:

GET/api/v1/demo-jobs/{job_id}/quality
GET /api/v1/demo-jobs/{job_id}/quality

Do not show a polished demo tenant if quality is unacceptable for your use case.

Step 4: Load core records

Recommended first load:

  1. accounts
  2. bank_accounts
  3. items
  4. customers
  5. vendors
  6. employees
  7. invoices
  8. credit_memos
  9. bills
  10. customer_payments
  11. vendor_payments
  12. bank_transactions
  13. journal_entries
  14. deals
  15. tasks
  16. payroll_runs

For ASC companies, add operating_rooms, surgical_cases, clinical_incidents, and dictation_scripts after the standard entities.

Fetch pages:

GET/api/v1/demo-jobs/{job_id}/entities/{entity}?limit=500&offset=0
GET /api/v1/demo-jobs/{job_id}/entities/{entity}?limit=500&offset=0

Step 5: Store lineage

For each imported record, store:

  • fictix_job_id
  • fictix_entity
  • fictix_record_id
  • fictix_loaded_at
  • fictix_dataset_hash, if available

Lineage makes support, debugging, and replays possible.

Step 6: Expose tenant state to users

Show:

  • company name
  • generated systems
  • loaded record counts
  • generation quality
  • last loaded timestamp
  • any warnings

Avoid showing raw Fictix credentials in UI.

Failure handling

Failure User-facing behavior Backend action
Auth failure Route a normal customer to the Console; approved integrations should contact Fictix support Verify exactly one approved management credential; do not retry with a project key, email/password, or browser session token
Generation budget exceeded Ask user to reduce scale Lower employees/months/services
Bundle too large Continue loading by entity Use entity pages
Quality failed Show warning or block launch Inspect quality endpoint
Loader partial failure Show partial state Resume from last entity/page

Production checklist

  • idempotency key is stable per user request
  • no management or project key in browser
  • generated data is marked synthetic in your product
  • loader is resumable
  • lineage is stored
  • quality endpoint is checked
  • counts are reconciled after load
  • runtime API key is encrypted or not stored