Sandbox Testing

Test your integration without making real filings. Use test API keys and magic company numbers to simulate different outcomes.

How It Works

Sandbox mode is activated automatically when you use a test API key (tt_test_...). In sandbox mode:

  • Full validation - Your requests are validated exactly like live mode
  • No real filings - Nothing is sent to HMRC or Companies House
  • No charges - Sandbox requests don't deduct from your balance
  • Deterministic outcomes - Use magic company numbers to test specific scenarios
  • Stateless - No database records are created

Magic Test Company Numbers

Use these special company numbers to trigger specific outcomes:

Company Number Jurisdiction Outcome Delay Description
00000001 England/Wales Accepted Poll required Standard success scenario
00000002 England/Wales Rejected Poll required UTR does not match company records
00000003 England/Wales Rejected Poll required Period has already been filed
00000004 England/Wales Error Poll required Gateway timeout (test retry logic)
00000005 England/Wales Accepted Immediate Immediate success (no polling needed)
SC000001 Scotland Accepted Poll required Scottish company success
SC000002 Scotland Rejected Poll required Company has been dissolved
NI000001 Northern Ireland Accepted Poll required Northern Irish company success
NI000002 Northern Ireland Rejected Poll required Company authentication code is invalid
Any other company number will be accepted when polled. Use the magic numbers above to test specific error scenarios.

Example: Submit a Sandbox CT600

# Use a test key (tt_test_...) and a magic company number
curl -X POST https://tinytax.co.uk/api/v1/filings/ct600 \
  -H "X-API-Key: tt_test_your_test_key_here" \
  -H "Idempotency-Key: sandbox-test-001" \
  -H "Content-Type: application/json" \
  -d '{
    "company_number": "00000001",
    "utr": "1234567890",
    "period_end": "2024-12-31",
    "credentials": {
      "government_gateway_id": "123456789012",
      "government_gateway_password": "any_password"
    }
  }'

Response:

{
  "success": true,
  "data": {
    "filing_id": "fil_test_ct600_00000001_a1b2c3d4e5f6",
    "status": "submitted",
    "sandbox": true,
    "message": "Sandbox submission - not filed to HMRC. Poll GET /filings/{filing_id} to get the final status.",
    "expected_outcome": "accepted"
  }
}

Polling for Status

After submitting, poll the filing endpoint to get the final status:

# Poll the sandbox filing ID (returned from submission)
curl https://tinytax.co.uk/api/v1/filings/fil_test_ct600_00000001_a1b2c3d4e5f6 \
  -H "X-API-Key: tt_test_your_test_key_here"

Initial submission returns submitted. Polling returns the final outcome:

{
  "success": true,
  "data": {
    "filing_id": "fil_test_ct600_00000001_a1b2c3d4e5f6",
    "status": "accepted",
    "sandbox": true,
    "company_number": "00000001",
    "hmrc_status": "accepted",
    "hmrc_correlation_id": "SANDBOX-CORR-A1B2C3D4E5F6",
    "hmrc_iru_number": "SANDBOX-IRU-A1B2C3"
  }
}
Stateless polling: Sandbox filings are not stored. Polling always returns the final status immediately. This simulates the complete submission → poll workflow without requiring actual time delays.

Filing ID Format

Sandbox filing IDs are deterministic and encode the scenario:

fil_test_{type}_{company}_{hash}

Example: fil_test_ct600_00000001_a1b2c3d4e5f6
         │       │      │         │
         │       │      │         └── Request hash (deterministic)
         │       │      └──────────── Company number (determines outcome)
         │       └─────────────────── Filing type (ct600 or accounts)
         └─────────────────────────── Sandbox prefix

The company number in the filing ID determines the outcome when polled. Same idempotency key + request always produces the same filing ID.

Idempotency in Sandbox

Sandbox idempotency is stateless:

  • Same idempotency key + same request body = same filing ID (deterministic)
  • Same idempotency key + different request body = different filing ID (no conflict error)

Filing IDs are generated by hashing the idempotency key with the request body. In sandbox mode, we don't store idempotency records, so conflicts are not enforced. Use live keys if you need to test idempotency conflict handling.

Listing Filings in Sandbox

Since sandbox filings are stateless (not stored), GET /filings returns an empty list:

{
  "success": true,
  "data": {
    "filings": [],
    "pagination": { "total": 0, "limit": 50, "offset": 0 },
    "sandbox": true,
    "message": "Sandbox mode - filings are stateless and not stored."
  }
}

Use the filing IDs from your submission responses to poll individual filing status.

Testing Different Jurisdictions

The magic company numbers include Scottish (SC) and Northern Irish (NI) prefixes to help you test:

  • Company number validation accepts all UK formats
  • Your integration handles 8-character and prefixed numbers correctly
  • Different rejection scenarios across jurisdictions