{"openapi":"3.0.3","info":{"title":"Rogue Mobile Partner API","version":"1.1.0","description":"Activate and renew lines, change plans, add topups, check usage and inventory, and run bulk jobs.\n\nStart with `POST /auth`, then send `Authorization: Bearer <token>` on every other call.\n\n`partner_id` is the id we issued you. Do not send extra identity fields on requests.\n\nSend a `txid` in the JSON body when you create a job. If you omit it, we mint a `tx_…` value and return it on the job and in `meta.txid`.\n\nA single-line job keeps that `txid`. A batch individualizes each line as `{txid}_{last8}` of the ESN or MDN (last 8 alphanumeric characters). Status, webhooks, and logs use those ids.\n\nLook up a job by `job_id`, parent `txid`, or per-line `txid` (`GET /jobs/{id}` or `GET /jobs?txid=`). Reusing a parent `txid` for the same partner returns 409.\n\n`Idempotency-Key` or a `txid` header is accepted if the body omits `txid`.\n\nAs each line finishes, we POST a signed webhook to the URL on your partner account (or the `webhook_url` on that job). See the Webhooks section for headers, signatures, and item vs job payloads.\n\n`GET /status` is public and does not require a token.","contact":{"name":"Rogue Mobile","email":"support@roguemobile.com","url":"https://www.roguemobile.com/"}},"servers":[{"url":"https://api.roguemobile.com/v1","description":"Production"}],"tags":[{"name":"Status","description":"Service health, line lookups, and usage"},{"name":"Auth"},{"name":"Plans","description":"Plan catalog and topup packs"},{"name":"Jobs","description":"Activations, renewals, plan changes, topups, and job status"},{"name":"Webhooks","description":"Inbound POSTs we send to your URL. These are not routes you call. Verify `X-RM-Signature` on every delivery."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"Meta":{"type":"object","properties":{"request_id":{"type":"string"},"job_id":{"type":"string"},"txid":{"type":"string","description":"Parent job txid"}}},"ServiceStatus":{"type":"object","properties":{"status":{"type":"string","enum":["operational","degraded","outage"]},"checked_at":{"type":"string","format":"date-time"},"services":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"status":{"type":"string","enum":["operational","degraded","outage"]},"detail":{"type":"string"}}}}}},"Token":{"type":"object","properties":{"token":{"type":"string"},"expires_in":{"type":"integer","example":1800},"token_type":{"type":"string","example":"Bearer"}}},"Plan":{"type":"object","properties":{"plan_id":{"type":"string"},"plan_code":{"type":"string"},"plan_name":{"type":"string"},"cost":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"null"}]}}},"CustomerLine":{"type":"object","properties":{"found":{"type":"boolean"},"mdn":{"type":"string"},"esn":{"type":"string","nullable":true},"sim":{"type":"string","nullable":true},"customer_id":{"type":"string","nullable":true},"enrollment_id":{"type":"string","nullable":true},"account_number":{"type":"string","nullable":true},"plan_id":{"type":"string","nullable":true},"plan_code":{"type":"string","nullable":true},"plan_name":{"type":"string","nullable":true},"zip":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"state":{"type":"string","nullable":true},"status":{"type":"string","nullable":true},"first_name":{"type":"string","nullable":true},"last_name":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"message":{"type":"string","nullable":true},"timestamp":{"type":"string","format":"date-time"}}},"InventoryStatus":{"type":"object","properties":{"esn":{"type":"string"},"status":{"type":"string","enum":["FREE","NOTFOUND","ACTIVE","ERROR"]},"message":{"type":"string"},"code":{"type":"string","nullable":true,"description":"Upstream status code when present"},"esn_status":{"type":"string","nullable":true},"provision_status":{"type":"string","nullable":true},"mdn":{"type":"string","nullable":true},"enrollment_id":{"type":"string","nullable":true},"zip":{"type":"string","nullable":true},"plan_code":{"type":"string","nullable":true},"plan_name":{"type":"string","nullable":true},"timestamp":{"type":"string","format":"date-time"}}},"Job":{"type":"object","properties":{"id":{"type":"string","example":"job_..."},"txid":{"type":"string","example":"order-99"},"partner_id":{"type":"string"},"type":{"type":"string","enum":["activation","renewal","plan_change","topup"]},"status":{"type":"string"},"totals":{"type":"object"},"defaults":{"type":"object"},"webhook_url":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"JobItem":{"type":"object","properties":{"id":{"type":"string","example":"itm_..."},"job_id":{"type":"string"},"txid":{"type":"string","description":"Line txid. Same as the job txid for a single line; `{txid}_{last8}` in a batch.","example":"order-99_56789012"},"job_txid":{"type":"string","example":"order-99"},"esn":{"type":"string","nullable":true},"status":{"type":"string"},"plan_code":{"type":"string","nullable":true},"plan_id":{"type":"string","nullable":true},"zip":{"type":"string","nullable":true},"request":{"type":"object","nullable":true},"result":{"type":"object","nullable":true},"last_error":{"type":"string","nullable":true},"attempt_count":{"type":"integer"},"started_at":{"type":"string","format":"date-time","nullable":true},"finished_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"JobDetail":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"},"items":{"type":"array","items":{"$ref":"#/components/schemas/JobItem"}},"match":{"type":"string","enum":["job_id","txid","item_txid"]}}},"ActivationItem":{"type":"object","required":["plan_code","zip"],"properties":{"esn":{"type":"string","minLength":8},"mdn":{"type":"string","description":"10-digit US phone number. Used to resolve the ESN when you do not send one."},"plan_code":{"type":"string"},"zip":{"type":"string","pattern":"^\\d{5}$"},"customer":{"type":"object","properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"},"zip":{"type":"string"}}}}},"ActivationRequest":{"type":"object","required":["items"],"properties":{"txid":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._:-]{1,64}$","description":"Your correlation id. Optional; we mint `tx_…` when omitted. Unique per partner. A single-line job keeps this value. A batch line becomes `{txid}_{last8}` of the ESN or MDN."},"items":{"type":"array","items":{"$ref":"#/components/schemas/ActivationItem"}},"defaults":{"type":"object","properties":{"enrollment_type":{"type":"string","example":"HANDOVER"},"carrier":{"type":"string","example":"TMB"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"state":{"type":"string"}}},"mode":{"type":"string","enum":["sync","async"]},"webhook_url":{"type":"string","format":"uri"}}},"RenewalRequest":{"type":"object","required":["items"],"properties":{"txid":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._:-]{1,64}$","description":"Your correlation id. Optional; we mint `tx_…` when omitted. Unique per partner. A single-line job keeps this value. A batch line becomes `{txid}_{last8}` of the ESN or MDN."},"items":{"type":"array","items":{"type":"object","properties":{"esn":{"type":"string"},"mdn":{"type":"string","description":"10-digit US phone number. Used to resolve the ESN when you do not send one."}}}},"plan_change":{"type":"boolean","default":false,"description":"Renew onto a different `plan_id`. For a plan change without a renewal, use `POST /jobs/plan-changes`."},"plan_id":{"type":"string","nullable":true,"description":"Required when `plan_change` is true."},"mode":{"type":"string","enum":["sync","async"]},"webhook_url":{"type":"string","format":"uri"}}},"PlanChangeRequest":{"type":"object","required":["items"],"properties":{"txid":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._:-]{1,64}$","description":"Your correlation id. Optional; we mint `tx_…` when omitted. Unique per partner. A single-line job keeps this value. A batch line becomes `{txid}_{last8}` of the ESN or MDN."},"items":{"type":"array","items":{"type":"object","properties":{"esn":{"type":"string"},"mdn":{"type":"string","description":"10-digit US phone number."},"plan_code":{"type":"string"},"plan_id":{"type":"string"},"zip":{"type":"string","pattern":"^\\d{5}$","description":"Required when resolving plan_code."},"change_type":{"type":"string","enum":["IMMEDIATE","ONEXPIRY"]}}}},"defaults":{"type":"object","properties":{"plan_code":{"type":"string"},"plan_id":{"type":"string"},"zip":{"type":"string","pattern":"^\\d{5}$"},"change_type":{"type":"string","enum":["IMMEDIATE","ONEXPIRY"]}}},"change_type":{"type":"string","enum":["IMMEDIATE","ONEXPIRY"],"description":"When the new plan takes effect. Default IMMEDIATE. ONEXPIRY waits until the current cycle ends."},"mode":{"type":"string","enum":["sync","async"]},"webhook_url":{"type":"string","format":"uri"}},"example":{"txid":"order-100","items":[{"mdn":"3125551234"}],"defaults":{"plan_id":"6664"},"change_type":"IMMEDIATE","mode":"sync"}},"Topup":{"type":"object","properties":{"topup_id":{"type":"string"},"topup_code":{"type":"string"},"topup_name":{"type":"string"},"cost":{"oneOf":[{"type":"string"},{"type":"number"},{"type":"null"}]}}},"TopupRequest":{"type":"object","required":["items"],"properties":{"txid":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._:-]{1,64}$","description":"Your correlation id. Optional; we mint `tx_…` when omitted. Unique per partner. A single-line job keeps this value. A batch line becomes `{txid}_{last8}` of the ESN or MDN."},"items":{"type":"array","items":{"type":"object","properties":{"esn":{"type":"string"},"mdn":{"type":"string","description":"10-digit US phone number."},"topup_code":{"type":"string"},"topup_id":{"type":"string"},"zip":{"type":"string","pattern":"^\\d{5}$","description":"Required when resolving topup_code."}}}},"defaults":{"type":"object","properties":{"topup_code":{"type":"string"},"topup_id":{"type":"string"},"zip":{"type":"string","pattern":"^\\d{5}$"}}},"mode":{"type":"string","enum":["sync","async"]},"webhook_url":{"type":"string","format":"uri"}},"example":{"txid":"order-101","items":[{"mdn":"3125551234"}],"defaults":{"topup_id":"88"},"mode":"sync"}},"Usage":{"type":"object","properties":{"mdn":{"type":"string"},"summary":{"type":"boolean"},"from":{"type":"string","format":"date","nullable":true},"to":{"type":"string","format":"date","nullable":true},"data_used":{"type":"string","nullable":true},"data_remaining":{"type":"string","nullable":true},"data_limit":{"type":"string","nullable":true},"talk_used":{"type":"string","nullable":true},"talk_remaining":{"type":"string","nullable":true},"text_used":{"type":"string","nullable":true},"text_remaining":{"type":"string","nullable":true},"records":{"type":"array","items":{"type":"object"}},"line_status":{"type":"string","nullable":true},"timestamp":{"type":"string","format":"date-time"}}},"WebhookItemData":{"type":"object","required":["job_id","item_id","status"],"properties":{"txid":{"type":"string","nullable":true,"description":"Line txid. Same as the job txid for a single line; `{txid}_{last8}` in a batch.","example":"order-99_56789012"},"job_txid":{"type":"string","nullable":true,"example":"order-99"},"job_id":{"type":"string","example":"job_01hxyz"},"item_id":{"type":"string","example":"itm_01hxyz"},"esn":{"type":"string","nullable":true},"status":{"type":"string","enum":["succeeded","failed"]},"customer_id":{"type":"string","nullable":true,"description":"Present on a successful activation."},"mdn":{"type":"string","nullable":true,"description":"Assigned number on a successful activation."},"enrollment_id":{"type":"string","nullable":true},"error":{"type":"string","description":"Present when `status` is `failed`."},"details":{"description":"Optional structured failure details."}},"additionalProperties":true},"WebhookJobData":{"type":"object","required":["job_id","status","total","succeeded","failed"],"properties":{"txid":{"type":"string","nullable":true,"description":"Parent job txid.","example":"order-99"},"job_txid":{"type":"string","nullable":true,"example":"order-99"},"job_id":{"type":"string","example":"job_01hxyz"},"status":{"type":"string","enum":["succeeded","failed","partial"]},"total":{"type":"integer","example":2},"succeeded":{"type":"integer","example":1},"failed":{"type":"integer","example":1}}},"WebhookItemEvent":{"type":"object","required":["id","type","created_at","data"],"properties":{"id":{"type":"string","example":"evt_01hxyz"},"type":{"type":"string","enum":["activation.item.succeeded","activation.item.failed","renewal.item.succeeded","renewal.item.failed","plan_change.item.succeeded","plan_change.item.failed","topup.item.succeeded","topup.item.failed"]},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/WebhookItemData"}}},"WebhookJobEvent":{"type":"object","required":["id","type","created_at","data"],"properties":{"id":{"type":"string","example":"evt_01hjob"},"type":{"type":"string","enum":["activation.job.completed","renewal.job.completed","plan_change.job.completed","topup.job.completed"]},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/WebhookJobData"}}},"WebhookEvent":{"oneOf":[{"$ref":"#/components/schemas/WebhookItemEvent"},{"$ref":"#/components/schemas/WebhookJobEvent"}]}}},"paths":{"/status":{"get":{"tags":["Status"],"summary":"Live service status","description":"Public health snapshot. No authentication required.","security":[],"responses":{"200":{"description":"Operational or degraded","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ServiceStatus"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"503":{"description":"Service disruption","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ServiceStatus"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}}}}},"/auth":{"post":{"tags":["Auth"],"summary":"Get a partner access token","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partner_id","api_key"],"properties":{"partner_id":{"type":"string","example":"your_partner_id","description":"The partner ID we issued you."},"api_key":{"type":"string","description":"The API key we issued you."}}}}}},"responses":{"200":{"description":"Token issued","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Token"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/plans":{"get":{"tags":["Plans"],"summary":"List plans for a ZIP","security":[{"bearerAuth":[]}],"parameters":[{"name":"zip","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{5}$"},"description":"5-digit US ZIP code"}],"responses":{"200":{"description":"Plans available for that ZIP","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Plan"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid ZIP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/topups":{"get":{"tags":["Plans"],"summary":"List topup packs for a ZIP","description":"Add-on packs you can apply with `POST /jobs/topups`. One pack per line per job.","security":[{"bearerAuth":[]}],"parameters":[{"name":"zip","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{5}$"},"description":"5-digit US ZIP code"}],"responses":{"200":{"description":"Topups available for that ZIP","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Topup"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid ZIP","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mdns/{mdn}":{"get":{"tags":["Status"],"summary":"Look up a line by phone number","description":"Returns ESN, SIM, plan, address, and account fields when the number is found.","security":[{"bearerAuth":[]}],"parameters":[{"name":"mdn","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"}}],"responses":{"200":{"description":"Line lookup","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CustomerLine"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid MDN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/mdns/{mdn}/usage":{"get":{"tags":["Status"],"summary":"Usage for a phone number","description":"Default is a 90-day summary (`summary=true`). Pass `from` and `to` (YYYY-MM-DD) for daily records. The range must fall in the last 90 days. Do not combine `summary=true` with a date range.","security":[{"bearerAuth":[]}],"parameters":[{"name":"mdn","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{10}$"}},{"name":"summary","in":"query","schema":{"type":"boolean"},"description":"Default true when `from`/`to` are omitted."},{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Usage","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Usage"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid MDN or date range","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Line not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/esns/{esn}/status":{"get":{"tags":["Status"],"summary":"Live inventory status","description":"FREE, NOTFOUND, ACTIVE, or ERROR for an ESN / ICCID.","security":[{"bearerAuth":[]}],"parameters":[{"name":"esn","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Inventory status","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/InventoryStatus"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/activations":{"post":{"tags":["Jobs"],"summary":"Create an activation job","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."},{"name":"txid","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivationRequest"}}}},"responses":{"200":{"description":"Sync job finished","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"202":{"description":"Async job accepted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate txid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/renewals":{"post":{"tags":["Jobs"],"summary":"Create a renewal job","description":"Keep the current plan, or set `plan_change` with `plan_id` to renew onto a different plan. For a plan change without a renewal, use `POST /jobs/plan-changes`.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."},{"name":"txid","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RenewalRequest"}}}},"responses":{"200":{"description":"Sync job finished","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"202":{"description":"Async job accepted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate txid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/plan-changes":{"post":{"tags":["Jobs"],"summary":"Create a plan-change job","description":"Move a live line to a different plan. `IMMEDIATE` applies now; `ONEXPIRY` waits until the current cycle ends. Send `plan_id` or `plan_code` (with zip) on each item or in defaults.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."},{"name":"txid","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanChangeRequest"}}}},"responses":{"200":{"description":"Sync job finished","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"202":{"description":"Async job accepted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate txid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/topups":{"post":{"tags":["Jobs"],"summary":"Create a topup job","description":"Add a data/talk/text pack to a live line. Send `topup_id` or `topup_code` (with zip). One pack per line per job.","security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."},{"name":"txid","in":"header","required":false,"schema":{"type":"string"},"description":"Used only if the body omits `txid`. Prefer JSON `txid`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupRequest"}}}},"responses":{"200":{"description":"Sync job finished","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"202":{"description":"Async job accepted","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Duplicate txid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs":{"get":{"tags":["Jobs"],"summary":"List jobs for the authenticated partner","security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}},{"name":"txid","in":"query","schema":{"type":"string"},"description":"Look up one job by parent txid or per-line item txid instead of listing."}],"responses":{"200":{"description":"Job list, or a single job when `txid` is set","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"oneOf":[{"type":"array","items":{"$ref":"#/components/schemas/Job"}},{"$ref":"#/components/schemas/JobDetail"}]},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found when looking up by txid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/{id}":{"get":{"tags":["Jobs"],"summary":"Get a job and its items","description":"`id` may be the `job_id`, the parent `txid`, or a per-line `{txid}_{last8}`. A line txid returns only that item.","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/JobDetail"},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/{id}/items":{"get":{"tags":["Jobs"],"summary":"List items on a job","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Items","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JobItem"}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/jobs/{id}/items/{itemId}/retry":{"post":{"tags":["Jobs"],"summary":"Retry a failed item","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"itemId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Retry queued","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"retried":{"type":"string"},"txid":{"type":"string"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/item":{"post":{"tags":["Webhooks"],"operationId":"webhookItemCompleted","servers":[{"url":"{webhook_url}","description":"The HTTPS URL on your partner account, or the per-job `webhook_url`","variables":{"webhook_url":{"default":"https://your.example/hooks/rogue-mobile"}}}],"security":[],"summary":"Line finished","description":"We POST this JSON to your HTTPS webhook URL. It is not a route you call on this API.\n\nSet the URL on your partner account (or pass `webhook_url` on the job). Respond `2xx` to acknowledge.\n\nVerify `X-RM-Signature: sha256=<hex>` with HMAC-SHA256 of the raw body and your webhook secret.\n\nFailed or timed-out deliveries retry up to 5 times with exponential backoff (30s, then doubling, capped at 15 minutes).\n\nSent after each activation, renewal, plan-change, or topup line finishes. `data.txid` is the line id.\n\nOn success, activation payloads also include `customer_id`, `mdn`, and `enrollment_id` when the upstream returns them.","parameters":[{"name":"X-RM-Event","in":"header","required":true,"schema":{"type":"string","enum":["activation.item.succeeded","activation.item.failed","activation.job.completed","renewal.item.succeeded","renewal.item.failed","renewal.job.completed","plan_change.item.succeeded","plan_change.item.failed","plan_change.job.completed","topup.item.succeeded","topup.item.failed","topup.job.completed"]},"description":"Same value as the JSON `type` field."},{"name":"X-RM-Delivery-Id","in":"header","required":true,"schema":{"type":"string","example":"del_01hxyz"},"description":"Delivery attempt id. Log this if you ask us to resend."},{"name":"X-RM-Signature","in":"header","required":true,"schema":{"type":"string","example":"sha256=0123456789abcdef"},"description":"HMAC-SHA256 of the raw request body using your webhook secret, prefixed with `sha256=`. Compare the full header to `sha256=` plus hex(`HMAC-SHA256(secret, raw_body)`)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookItemEvent"},"examples":{"succeeded":{"summary":"Activation line succeeded","value":{"id":"evt_01hxyz","type":"activation.item.succeeded","created_at":"2026-09-15T20:00:00.000Z","data":{"txid":"order-99_56789012","job_txid":"order-99","job_id":"job_01hxyz","item_id":"itm_01hxyz","esn":"8901260123456789012","status":"succeeded","customer_id":"12345678","mdn":"5855550100","enrollment_id":"987654"}}},"failed":{"summary":"Activation line failed","value":{"id":"evt_01hfail","type":"activation.item.failed","created_at":"2026-09-15T20:00:01.000Z","data":{"txid":"order-99_56789013","job_txid":"order-99","job_id":"job_01hxyz","item_id":"itm_01hfail","esn":"8901260123456789013","status":"failed","error":"Service not available for this ZIP"}}}}}}},"responses":{"200":{"description":"Acknowledged. Any `2xx` stops retries."}}}},"/webhooks/job":{"post":{"tags":["Webhooks"],"operationId":"webhookJobCompleted","servers":[{"url":"{webhook_url}","description":"The HTTPS URL on your partner account, or the per-job `webhook_url`","variables":{"webhook_url":{"default":"https://your.example/hooks/rogue-mobile"}}}],"security":[],"summary":"Job finished","description":"We POST this JSON to your HTTPS webhook URL. It is not a route you call on this API.\n\nSet the URL on your partner account (or pass `webhook_url` on the job). Respond `2xx` to acknowledge.\n\nVerify `X-RM-Signature: sha256=<hex>` with HMAC-SHA256 of the raw body and your webhook secret.\n\nFailed or timed-out deliveries retry up to 5 times with exponential backoff (30s, then doubling, capped at 15 minutes).\n\nSent once every line on the job has succeeded or failed. `data.txid` is the parent job txid.\n\n`data.status` is `succeeded` (all lines ok), `failed` (all lines failed), or `partial`.","parameters":[{"name":"X-RM-Event","in":"header","required":true,"schema":{"type":"string","enum":["activation.item.succeeded","activation.item.failed","activation.job.completed","renewal.item.succeeded","renewal.item.failed","renewal.job.completed","plan_change.item.succeeded","plan_change.item.failed","plan_change.job.completed","topup.item.succeeded","topup.item.failed","topup.job.completed"]},"description":"Same value as the JSON `type` field."},{"name":"X-RM-Delivery-Id","in":"header","required":true,"schema":{"type":"string","example":"del_01hxyz"},"description":"Delivery attempt id. Log this if you ask us to resend."},{"name":"X-RM-Signature","in":"header","required":true,"schema":{"type":"string","example":"sha256=0123456789abcdef"},"description":"HMAC-SHA256 of the raw request body using your webhook secret, prefixed with `sha256=`. Compare the full header to `sha256=` plus hex(`HMAC-SHA256(secret, raw_body)`)."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookJobEvent"},"examples":{"completed":{"summary":"Job completed with mixed results","value":{"id":"evt_01hjob","type":"activation.job.completed","created_at":"2026-09-15T20:00:02.000Z","data":{"txid":"order-99","job_txid":"order-99","job_id":"job_01hxyz","status":"partial","total":2,"succeeded":1,"failed":1}}}}}}},"responses":{"200":{"description":"Acknowledged. Any `2xx` stops retries."}}}}},"webhooks":{"itemCompleted":{"post":{"tags":["Webhooks"],"summary":"Line finished","description":"POSTed to your webhook URL after each line finishes. Verify `X-RM-Signature: sha256=<hmac>` using your webhook secret over the raw body.","parameters":[{"name":"X-RM-Event","in":"header","required":true,"schema":{"type":"string","enum":["activation.item.succeeded","activation.item.failed","activation.job.completed","renewal.item.succeeded","renewal.item.failed","renewal.job.completed","plan_change.item.succeeded","plan_change.item.failed","plan_change.job.completed","topup.item.succeeded","topup.item.failed","topup.job.completed"]},"description":"Same value as the JSON `type` field."},{"name":"X-RM-Delivery-Id","in":"header","required":true,"schema":{"type":"string","example":"del_01hxyz"},"description":"Delivery attempt id. Log this if you ask us to resend."},{"name":"X-RM-Signature","in":"header","required":true,"schema":{"type":"string","example":"sha256=0123456789abcdef"},"description":"HMAC-SHA256 of the raw request body using your webhook secret, prefixed with `sha256=`. Compare the full header to `sha256=` plus hex(`HMAC-SHA256(secret, raw_body)`)."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookItemEvent"},"example":{"id":"evt_01hxyz","type":"activation.item.succeeded","created_at":"2026-09-15T20:00:00.000Z","data":{"txid":"order-99_56789012","job_txid":"order-99","job_id":"job_01hxyz","item_id":"itm_01hxyz","esn":"8901260123456789012","status":"succeeded","customer_id":"12345678","mdn":"5855550100","enrollment_id":"987654"}}}}},"responses":{"200":{"description":"Acknowledged"}}}},"jobCompleted":{"post":{"tags":["Webhooks"],"summary":"Job finished","description":"POSTed to your webhook URL when every line on the job has a final status.","parameters":[{"name":"X-RM-Event","in":"header","required":true,"schema":{"type":"string","enum":["activation.item.succeeded","activation.item.failed","activation.job.completed","renewal.item.succeeded","renewal.item.failed","renewal.job.completed","plan_change.item.succeeded","plan_change.item.failed","plan_change.job.completed","topup.item.succeeded","topup.item.failed","topup.job.completed"]},"description":"Same value as the JSON `type` field."},{"name":"X-RM-Delivery-Id","in":"header","required":true,"schema":{"type":"string","example":"del_01hxyz"},"description":"Delivery attempt id. Log this if you ask us to resend."},{"name":"X-RM-Signature","in":"header","required":true,"schema":{"type":"string","example":"sha256=0123456789abcdef"},"description":"HMAC-SHA256 of the raw request body using your webhook secret, prefixed with `sha256=`. Compare the full header to `sha256=` plus hex(`HMAC-SHA256(secret, raw_body)`)."}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookJobEvent"},"example":{"id":"evt_01hjob","type":"activation.job.completed","created_at":"2026-09-15T20:00:02.000Z","data":{"txid":"order-99","job_txid":"order-99","job_id":"job_01hxyz","status":"partial","total":2,"succeeded":1,"failed":1}}}}},"responses":{"200":{"description":"Acknowledged"}}}}}}