{
  "name": "Test Helper API",
  "version": "v1",
  "baseUrl": "https://api.testdata.help/v1",
  "mailDomain": "testdata.help",
  "docs": {
    "llms": "https://api.testdata.help/v1/llms.txt",
    "openapi": "https://api.testdata.help/v1/openapi.json",
    "apiCatalog": "https://api.testdata.help/.well-known/api-catalog"
  },
  "conventions": [
    "Every action answers GET: {baseUrl}/<service>/<action>?param=value.",
    "Parameter names are lower case and case-insensitive; names ending in 64 take base64.",
    "key = your namespace; use a fresh one per test run (lists/codes -> rand10).",
    "No authentication. Responses are camelCase JSON; times are UTC epoch seconds.",
    "Empty queue = HTTP 200 with exhausted:true. Errors = {\"error\": \"...\", \"status\": N}."
  ],
  "services": [
    {
      "name": "lists",
      "description": "Keyed test-data queues shared by every virtual user: push/pop/random records, bulk CSV/JSON import (atomic replace), run-scoped variables, atomic counters, and a cleanup register for records a test created.",
      "url": "https://api.testdata.help/v1/lists",
      "actions": [
        {
          "action": "push",
          "url": "https://api.testdata.help/v1/lists/push",
          "methods": [
            "GET"
          ],
          "summary": "Append a record to a key's queue"
        },
        {
          "action": "pop",
          "url": "https://api.testdata.help/v1/lists/pop",
          "methods": [
            "GET"
          ],
          "summary": "Take the next record (each record is handed out once)"
        },
        {
          "action": "random",
          "url": "https://api.testdata.help/v1/lists/random",
          "methods": [
            "GET"
          ],
          "summary": "A random record, without consuming it"
        },
        {
          "action": "list",
          "url": "https://api.testdata.help/v1/lists/list",
          "methods": [
            "GET"
          ],
          "summary": "Read the records of a key (paged for large keys)"
        },
        {
          "action": "reset",
          "url": "https://api.testdata.help/v1/lists/reset",
          "methods": [
            "GET"
          ],
          "summary": "Rewind the pop pointer to record 1"
        },
        {
          "action": "clear",
          "url": "https://api.testdata.help/v1/lists/clear",
          "methods": [
            "GET"
          ],
          "summary": "Delete every record of a key"
        },
        {
          "action": "codes",
          "url": "https://api.testdata.help/v1/lists/codes",
          "methods": [
            "GET"
          ],
          "summary": "Random uppercase alphanumeric codes (3, 4, 6, 8 and 10 characters)"
        },
        {
          "action": "vars/set",
          "url": "https://api.testdata.help/v1/lists/vars/set",
          "methods": [
            "GET"
          ],
          "summary": "Save a run-scoped variable under a key"
        },
        {
          "action": "vars/get",
          "url": "https://api.testdata.help/v1/lists/vars/get",
          "methods": [
            "GET"
          ],
          "summary": "Read a variable"
        },
        {
          "action": "vars/list",
          "url": "https://api.testdata.help/v1/lists/vars/list",
          "methods": [
            "GET"
          ],
          "summary": "List every variable of a key"
        },
        {
          "action": "counters/add",
          "url": "https://api.testdata.help/v1/lists/counters/add",
          "methods": [
            "GET"
          ],
          "summary": "Advance a counter atomically"
        },
        {
          "action": "counters/get",
          "url": "https://api.testdata.help/v1/lists/counters/get",
          "methods": [
            "GET"
          ],
          "summary": "Read a counter without changing it"
        },
        {
          "action": "cleanup/push",
          "url": "https://api.testdata.help/v1/lists/cleanup/push",
          "methods": [
            "GET"
          ],
          "summary": "Register a record that will need removing"
        },
        {
          "action": "cleanup/pop",
          "url": "https://api.testdata.help/v1/lists/cleanup/pop",
          "methods": [
            "GET"
          ],
          "summary": "Hand back the next record to remove"
        },
        {
          "action": "cleanup/list",
          "url": "https://api.testdata.help/v1/lists/cleanup/list",
          "methods": [
            "GET"
          ],
          "summary": "The cleanup audit trail"
        },
        {
          "action": "upload",
          "url": "https://api.testdata.help/v1/lists/upload",
          "methods": [
            "GET"
          ],
          "summary": "Drag-and-drop CSV/JSON loader (HTML page)"
        },
        {
          "action": "upload/url",
          "url": "https://api.testdata.help/v1/lists/upload/url",
          "methods": [
            "GET"
          ],
          "summary": "Presigned S3 POST for a CSV/JSON file of up to 50 MB"
        },
        {
          "action": "import",
          "url": "https://api.testdata.help/v1/lists/import",
          "methods": [
            "GET",
            "POST"
          ],
          "summary": "Replace a key's records from an uploaded file (ref)"
        },
        {
          "action": "import/status",
          "url": "https://api.testdata.help/v1/lists/import/status",
          "methods": [
            "GET"
          ],
          "summary": "Progress or result of an import"
        }
      ]
    },
    {
      "name": "names",
      "description": "Regional personas for test data: a female and a male name sharing a surname, with ASCII-folded forms. Repeatable with seed. 15 regions, in memory.",
      "url": "https://api.testdata.help/v1/names",
      "actions": [
        {
          "action": "get",
          "url": "https://api.testdata.help/v1/names/get",
          "methods": [
            "GET"
          ],
          "summary": "A female and a male persona for a region"
        },
        {
          "action": "regions",
          "url": "https://api.testdata.help/v1/names/regions",
          "methods": [
            "GET"
          ],
          "summary": "List the available regions and their list sizes"
        }
      ]
    },
    {
      "name": "mail",
      "description": "Inbound mail catcher (any address at the mail domain, popped per address), outbound send through SES with generated, saved or received attachments, and an attachment store with text search inside PDF, Office and text files.",
      "url": "https://api.testdata.help/v1/mail",
      "actions": [
        {
          "action": "pop",
          "url": "https://api.testdata.help/v1/mail/pop",
          "methods": [
            "GET"
          ],
          "summary": "Take the next captured email for an address"
        },
        {
          "action": "reset",
          "url": "https://api.testdata.help/v1/mail/reset",
          "methods": [
            "GET"
          ],
          "summary": "Rewind an address's pointer to its first message"
        },
        {
          "action": "clear",
          "url": "https://api.testdata.help/v1/mail/clear",
          "methods": [
            "GET"
          ],
          "summary": "Delete every captured email for an address"
        },
        {
          "action": "send",
          "url": "https://api.testdata.help/v1/mail/send",
          "methods": [
            "GET",
            "POST"
          ],
          "summary": "Send an email (query-string form)"
        },
        {
          "action": "attachments/save",
          "url": "https://api.testdata.help/v1/mail/attachments/save",
          "methods": [
            "GET",
            "POST"
          ],
          "summary": "Save a received attachment under a key (promote)"
        },
        {
          "action": "attachments/get",
          "url": "https://api.testdata.help/v1/mail/attachments/get",
          "methods": [
            "GET"
          ],
          "summary": "Fetch a saved or received attachment"
        },
        {
          "action": "attachments/delete",
          "url": "https://api.testdata.help/v1/mail/attachments/delete",
          "methods": [
            "GET"
          ],
          "summary": "Delete a saved attachment"
        },
        {
          "action": "attachments/find",
          "url": "https://api.testdata.help/v1/mail/attachments/find",
          "methods": [
            "GET"
          ],
          "summary": "Search inside an attachment without downloading it"
        },
        {
          "action": "attachments/upload",
          "url": "https://api.testdata.help/v1/mail/attachments/upload",
          "methods": [
            "GET"
          ],
          "summary": "Browser page for uploading saved attachments"
        },
        {
          "action": "attachments/upload/url",
          "url": "https://api.testdata.help/v1/mail/attachments/upload/url",
          "methods": [
            "GET"
          ],
          "summary": "Presigned S3 POST for uploading a large saved attachment"
        }
      ]
    },
    {
      "name": "totp",
      "description": "TOTP secret store and RFC 6238 code generation for MFA-protected test accounts.",
      "url": "https://api.testdata.help/v1/totp",
      "actions": [
        {
          "action": "set",
          "url": "https://api.testdata.help/v1/totp/set",
          "methods": [
            "GET"
          ],
          "summary": "Store a TOTP secret for a user"
        },
        {
          "action": "get",
          "url": "https://api.testdata.help/v1/totp/get",
          "methods": [
            "GET"
          ],
          "summary": "Get the current, next and previous TOTP codes"
        }
      ]
    },
    {
      "name": "webhook",
      "description": "Capture inbound webhooks from a system under test and read them back.",
      "url": "https://api.testdata.help/v1/webhook",
      "actions": [
        {
          "action": "receive",
          "url": "https://api.testdata.help/v1/webhook/receive",
          "methods": [
            "DELETE",
            "GET",
            "PATCH",
            "POST",
            "PUT"
          ],
          "summary": "Capture an inbound webhook (any method)"
        },
        {
          "action": "list",
          "url": "https://api.testdata.help/v1/webhook/list",
          "methods": [
            "GET"
          ],
          "summary": "List captured webhooks for a key (newest first)"
        },
        {
          "action": "clear",
          "url": "https://api.testdata.help/v1/webhook/clear",
          "methods": [
            "GET"
          ],
          "summary": "Delete all captured webhooks for a key"
        }
      ]
    },
    {
      "name": "lock",
      "description": "Short-lived (60 s, no renew) mutual exclusion between concurrent test scripts that share one resource. Contention is 200 with locked:false.",
      "url": "https://api.testdata.help/v1/lock",
      "actions": [
        {
          "action": "acquire",
          "url": "https://api.testdata.help/v1/lock/acquire",
          "methods": [
            "GET"
          ],
          "summary": "Take a short-lived lock on a shared resource"
        },
        {
          "action": "release",
          "url": "https://api.testdata.help/v1/lock/release",
          "methods": [
            "GET"
          ],
          "summary": "Release a lock you hold"
        }
      ]
    },
    {
      "name": "qr",
      "description": "QR codes from text, as JSON (PNG as base64 and a data: URI), SVG, or a self-contained HTML page. Pure computation, no storage.",
      "url": "https://api.testdata.help/v1/qr",
      "actions": [
        {
          "action": "get",
          "url": "https://api.testdata.help/v1/qr/get",
          "methods": [
            "GET"
          ],
          "summary": "Encode text as a QR code (JSON, SVG or HTML page)"
        }
      ]
    },
    {
      "name": "perf",
      "description": "Record performance data points from test scripts and read back exact counts, means and bounds, histogram percentiles (~2% relative accuracy), per-minute time series and pass/fail gates.",
      "url": "https://api.testdata.help/v1/perf",
      "actions": [
        {
          "action": "add",
          "url": "https://api.testdata.help/v1/perf/add",
          "methods": [
            "GET"
          ],
          "summary": "Record one or more performance data points"
        },
        {
          "action": "stats",
          "url": "https://api.testdata.help/v1/perf/stats",
          "methods": [
            "GET"
          ],
          "summary": "Summary statistics for a key"
        },
        {
          "action": "series",
          "url": "https://api.testdata.help/v1/perf/series",
          "methods": [
            "GET"
          ],
          "summary": "Bucketed time series for a key"
        },
        {
          "action": "assert",
          "url": "https://api.testdata.help/v1/perf/assert",
          "methods": [
            "GET"
          ],
          "summary": "Pass/fail performance gate"
        },
        {
          "action": "keys",
          "url": "https://api.testdata.help/v1/perf/keys",
          "methods": [
            "GET"
          ],
          "summary": "List the keys that have recorded results"
        },
        {
          "action": "clear",
          "url": "https://api.testdata.help/v1/perf/clear",
          "methods": [
            "GET"
          ],
          "summary": "Delete everything recorded for a key"
        },
        {
          "action": "export",
          "url": "https://api.testdata.help/v1/perf/export",
          "methods": [
            "GET"
          ],
          "summary": "Export the individual points for a key"
        }
      ]
    }
  ]
}