{"openapi":"3.1.0","info":{"title":"numtrue API","version":"1.0.0","description":"Welcome to the numtrue API.\n\nnumtrue checks whether a phone number is real, not just correctly formatted. We query it directly against its carrier network (HLR), so what you get back is live, not cached or guessed.\n\n## Terms\n\n- **HLR (Home Location Register)**: the carrier's own database. Tells us if a number is active, reachable, and which network it's on right now.\n- **MNP (Mobile Number Portability)**: the registry of which carrier a number has been ported to. We use this as a fallback where live HLR isn't available.\n\n## What you get back\n\nEvery check tells you:\n\n1. Is the number active?\n2. Is it reachable right now?\n3. Which carrier it's on\n4. Whether it was ever ported\n5. Line type: mobile, landline, or VoIP\n6. Whether it's disposable\n\n> **Note:** Some countries don't expose live HLR data (confirmed: **US, Mexico, China, Brazil**). For these we automatically fall back to MNP, no setup needed on your end. You just lose the \"reachable right now\" signal; everything else still comes back as usual.\n\n## Billing\n\n1 credit per check. Invalid numbers or failed lookups are never charged.\n\n## Rate limits\n\n150 requests / minute per IP address.\n\n## Getting Started\n\n1. [Sign up](/auth) to get your API key (starts with `ntk_`)\n2. Use it as a Bearer token: `Authorization: Bearer ntk_...`\n3. Call `/api/lookups` with `{ \"number\": \"+14155552671\" }`"},"servers":[{"url":"https://numtrue.com","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Paste your API key from the dashboard. Keys start with `ntk_`."}}},"paths":{"/api/lookups":{"post":{"tags":["Lookups"],"summary":"Lookup a phone number","description":"Check a single number and get carrier, line type, reachability, ported status, and disposable flag back.\n\nWe try a live HLR query first. If the destination doesn't support it, we automatically fall back to MNP, no setup needed on your end. Check `lookupMethod` in the response to see which one ran.\n\n> **Note:** You're only charged if we actually reach a carrier. Invalid numbers and failed lookups are refunded automatically.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["number"],"properties":{"number":{"type":"string","example":"+14155552671"}}}}}},"responses":{"200":{"description":"Successful lookup","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"msisdn":{"type":"string"},"status":{"type":"string","enum":["active","inactive","invalid","unknown","data_only","failed"],"description":"What the lookup found:\n\n- `active`: Live and reachable on the network right now.\n- `inactive`: Confirmed unreachable, the device is off or out of service.\n- `unknown`: Reachability couldn't be determined (the result came back via MNP, or HLR was inconclusive).\n- `invalid`: The number doesn't exist or is malformed.\n- `data_only`: Data SIM, IoT device, or hotspot, no voice or SMS capability.\n- `failed`: The lookup itself errored (network issue, provider down). You were refunded; try rechecking."},"reachable":{"type":"boolean"},"lineType":{"type":"string"},"isPorted":{"type":"boolean","nullable":true},"isDisposable":{"type":"boolean"},"network":{"type":"string","nullable":true},"portedFrom":{"type":"string","nullable":true},"country":{"type":"string"},"area":{"type":"string","nullable":true},"mcc":{"type":"string","nullable":true},"mnc":{"type":"string","nullable":true},"lookupMethod":{"type":"string","nullable":true,"enum":["HLR","MNP"],"description":"null means only free validation ran, no charge."}}}},"example":{"success":true,"data":{"msisdn":"14155552671","status":"unknown","reachable":false,"lineType":"mobile","isPorted":null,"isDisposable":false,"network":"T-Mobile USA","portedFrom":null,"country":"US","area":"California","mcc":"310","mnc":"260","lookupMethod":"MNP"}}}}}},"401":{"description":"Invalid or missing API key"},"402":{"description":"Insufficient credits"},"500":{"description":"Lookup failed (network error, provider down)"}}}},"/api/batches":{"get":{"tags":["Batches"],"summary":"List batches","description":"All your batches, newest first, with a running count of numbers in each.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Array of batches","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED"],"description":"Batch lifecycle:\n\n- `PENDING`: created, about to start.\n- `PROCESSING`: numbers are being checked right now, poll for updates.\n- `COMPLETED`: every number has a final result (`doneCount` equals `totalCount`).\n- `FAILED`: every number was rejected by the lookup provider; credits were refunded, nothing to poll for."},"totalCount":{"type":"integer"},"doneCount":{"type":"integer"},"fileName":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"_count":{"type":"object","properties":{"numbers":{"type":"integer"}}}}},"example":[{"id":"cm7x9k2a30001abc123def456","status":"COMPLETED","totalCount":500,"doneCount":500,"fileName":"leads-q3.csv","createdAt":"2026-07-14T08:30:00.000Z","updatedAt":"2026-07-14T08:32:15.000Z","_count":{"numbers":500}}]}}}},"401":{"description":"Invalid or missing API key"}}},"post":{"tags":["Batches"],"summary":"Create a batch","description":"Check up to 100,000 numbers at once. Same HLR-then-MNP flow as the single lookup, just in bulk.\n\nCredits for every number are reserved upfront, then refunded for anything invalid or failed once the batch finishes.\n\n> **Note:** This endpoint is async. It returns right away with a `batchId`; poll `GET /api/batches/{id}` for results.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["numbers"],"properties":{"numbers":{"type":"array","minItems":1,"maxItems":100000,"items":{"type":"string"},"example":["+14155552671","+447700900001"]},"fileName":{"type":"string","example":"leads-q3.csv"}}}}}},"responses":{"200":{"description":"Batch created and submitted","content":{"application/json":{"schema":{"type":"object","properties":{"batchId":{"type":"string"},"status":{"type":"string"},"total":{"type":"integer"},"accepted":{"type":"integer"},"rejected":{"type":"integer"}}},"example":{"batchId":"cm7x9k2a30001abc123def456","status":"PROCESSING","total":2,"accepted":2,"rejected":0}}}},"401":{"description":"Invalid or missing API key"},"402":{"description":"Insufficient credits"},"502":{"description":"All numbers rejected by the lookup provider"}}}},"/api/batches/{id}":{"get":{"tags":["Batches"],"summary":"Get batch results","description":"A batch and every number result inside it.\n\n> **Note:** If the batch was shared publicly (`public_access: true`), this works without an API key.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Batch with results","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","PROCESSING","COMPLETED","FAILED"]},"totalCount":{"type":"integer"},"doneCount":{"type":"integer"},"fileName":{"type":"string","nullable":true},"public_access":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"numbers":{"type":"array","items":{"type":"object","properties":{"msisdn":{"type":"string"},"status":{"type":"string","enum":["processing","active","inactive","invalid","unknown","data_only","failed"],"description":"What the check found:\n\n- `processing`: Still being checked, not done yet, poll again shortly.\n- `active`: Live and reachable on the network right now.\n- `inactive`: Confirmed unreachable, the device is off or out of service.\n- `unknown`: Reachability couldn't be determined (the result came back via MNP, or HLR was inconclusive).\n- `invalid`: The number doesn't exist or is malformed.\n- `data_only`: Data SIM, IoT device, or hotspot, no voice or SMS capability.\n- `failed`: The lookup itself errored. You were refunded for this number."},"reachable":{"type":"boolean"},"lineType":{"type":"string"},"isPorted":{"type":"boolean","nullable":true},"isDisposable":{"type":"boolean"},"network":{"type":"string","nullable":true},"portedFrom":{"type":"string","nullable":true},"country":{"type":"string"},"area":{"type":"string","nullable":true},"mcc":{"type":"string","nullable":true},"mnc":{"type":"string","nullable":true},"lookupMethod":{"type":"string","nullable":true,"enum":["HLR","MNP"]}}}}},"example":{"id":"cm7x9k2a30001abc123def456","status":"COMPLETED","totalCount":2,"doneCount":2,"fileName":"leads-q3.csv","public_access":false,"createdAt":"2026-07-14T08:30:00.000Z","updatedAt":"2026-07-14T08:32:15.000Z","numbers":[{"msisdn":"14155552671","status":"unknown","reachable":false,"lineType":"mobile","isPorted":null,"isDisposable":false,"network":"T-Mobile USA","portedFrom":null,"country":"US","area":"California","mcc":"310","mnc":"260","lookupMethod":"MNP"},{"msisdn":"447700900001","status":"active","reachable":true,"lineType":"mobile","isPorted":true,"isDisposable":false,"network":"Vodafone UK","portedFrom":"EE","country":"GB","area":null,"mcc":"234","mnc":"15","lookupMethod":"HLR"}]}}}}},"401":{"description":"Authentication required for private batches"},"403":{"description":"Access denied: batch is private and you are not the owner"},"404":{"description":"Batch not found"}}}},"/api/user/me":{"get":{"tags":["Account"],"summary":"Get account info","description":"Your account info: name, email, and current credit balance.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account info","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"credits":{"type":"integer"},"hasApiKey":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"example":{"id":"cm7x9k2a30001abc123def456","email":"dev@numtrue.com","name":"Jane Doe","credits":248,"hasApiKey":true,"createdAt":"2026-01-15T10:30:00.000Z"}}}},"401":{"description":"Invalid or missing API key"}}}},"/api/user/keys":{"post":{"tags":["Account"],"summary":"Generate or rotate your API key","description":"Generates a new API key. This immediately invalidates any key you had before, so update your integrations right after rotating.\n\n> **Note:** The raw key is only shown once, right here. We only store a hash of it, so if you lose it, you'll need to generate a new one.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"New API key","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string"}}},"example":{"key":"ntk_a1b2c3d4e5f6..."}}}},"401":{"description":"Invalid or missing API key"}}}}}}