Partner API documentation

G-Starlink Hub Partner API

Version 1.0.0 · https://api.gstarlink.com

Download OpenAPI YAML

Authentication

OAuth 2.0 token management

POST/api/v1/oauth/token

Get access token

Exchange client credentials for a Bearer access token. Supports both JSON and form-urlencoded request bodies.

Request body*application/json, application/x-www-form-urlencoded

Responses

200Access token issued
400Invalid request or scope
401Invalid credentials
403Partner account suspended

Products

Browse eSIM product catalog

GET/api/v1/productsrequires auth

List products

Browse available eSIM products with filtering and pagination.

Parameters

NameInTypeDescription
limitqueryinteger
cursorquerystringOpaque pagination cursor from previous response
regionquerystringFilter by region (e.g. "Global", "Europe", "Asia")
typequerystringFilter by eSIM type
statusquerystring
sort_byquerystring
sort_orderqueryenum

Responses

200Product list
400
401
429
GET/api/v1/products/{id}requires auth

Get product details

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Product details
401
404

Orders

Create and manage orders

GET/api/v1/ordersrequires auth

List orders

List your orders with optional status filter and cursor pagination.

Parameters

NameInTypeDescription
limitqueryinteger
cursorquerystring
statusqueryenum

Responses

200Order list
401
429
POST/api/v1/ordersrequires auth

Create order

Create a new order. Requires Idempotency-Key header to prevent duplicates. If the same key is reused, the original order is returned with Idempotent-Replayed: true header.

Payment: production orders are charged atomically to the partner's pre-funded wallet and are created as paid. If the balance is insufficient the order is NOT created and 402 Insufficient Balance is returned with the shortfall. Sandbox orders simulate payment — the wallet is never charged. Check the balance with GET /api/v1/balance.

Parameters

NameInTypeDescription
Idempotency-Key*headerstringUnique key to prevent duplicate orders

Request body*application/json

Responses

200Idempotent replay (order already exists)
201Order created
400Validation error, invalid product, or missing activation request
401
402Wallet balance too low — no order created and no funds taken
429
GET/api/v1/orders/{id}requires auth

Get order with fulfillment details

Returns order details including line items and fulfillment information (shipping tracking, eSIM codes, etc.)

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Order with fulfillment
401
404
GET/api/v1/orders/{id}/activation-statusrequires auth

Get activation status for an order

Returns the status of all scheduled activations associated with an order.

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Activation status details
401
404
POST/api/v1/orders/bulkrequires auth

Create bulk orders

Create up to 100 orders in a single request. Each order is processed independently; individual failures do not affect other orders in the batch.

Request body*application/json

Responses

200Bulk order results
400Validation error
401

Activations

Physical SIM activation requests and status

GET/api/v1/activationsrequires auth

List activation requests

List your physical SIM activation requests with optional filters.

Parameters

NameInTypeDescription
iccidquerystringFilter by SIM number
statusqueryenum
limitqueryinteger

Responses

200Activation request list
401
429
POST/api/v1/activationsrequires auth

Submit physical SIM activation

Submit a physical SIM card activation request with KYC data. The system auto-detects the carrier from the ICCID prefix:

  • 896103* = Lycamobile
  • 58* = Optus

Currently supported carriers: Lycamobile and Optus. ICCIDs for other carriers return 422 Carrier Not Supported with a supported_carriers list.

KYC requirements differ by carrier (all listed fields required):

  • Lycamobile: first_name, last_name, passport_no, passport_country, passport_expiry, date_of_birth, address, sim_last4, puk
  • Optus: first_name, last_name, passport_no, passport_country, passport_expiry, date_of_birth, address, title

Request body*application/json

Responses

201Activation request created
400Validation error or missing KYC fields
401
409Duplicate ICCID or date conflict
429
GET/api/v1/activations/{id}requires auth

Get activation details

Get detailed status of a specific activation request, including assigned mobile number and any error information.

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Activation details
401
404
PATCH/api/v1/activations/{id}requires auth

Reschedule an activation request

Edit the requested activation date and/or note on an in-flight activation request. At least one of the two fields is required.

Only editable while status = "activation_requested". Once ops has submitted the request to the carrier (or it has moved past that state for any other reason), this returns 409 naming the current status — coordinate with support instead. No KYC or customer fields can be changed here; those go through the KYC pool endpoints.

Not found, or the activation belongs to another partner — 404 (existence is never leaked).

Parameters

NameInTypeDescription
id*pathstring · uuid

Request body*application/json

Responses

200Activation rescheduled
400Validation error (no editable field, or a bad date)
401
404
409Not editable — activation is no longer 'activation_requested'
429
POST/api/v1/activations/{id}/cancelrequires auth

Cancel an activation request

Cancel an in-flight activation request.

Only cancellable while status = "activation_requested". Once ops has submitted the request to the carrier, this returns 409 naming the current status — contact support instead. Cancelling atomically releases any KYC-pool passport draw (the passport's per-brand use count and assigned_request_id are cleared, so it never falsely counts toward its 4-use cap) and rolls the SIM's activation status back to Inactive, so it becomes resubmittable.

Not found, or the activation belongs to another partner — 404 (existence is never leaked).

Parameters

NameInTypeDescription
id*pathstring · uuid

Request bodyapplication/json

Responses

200Activation cancelled
401
404
409Not cancellable — activation is no longer 'activation_requested'
429
POST/api/v1/activations/by-iccid/{iccid}/cancelrequires auth

Cancel an activation request, looked up by ICCID

Same atomic core as POST /api/v1/activations/{id}/cancel — for callers (e.g. ICC's automation) that hold the ICCID rather than our internal activation id, so no extra GET /api/v1/activations lookup is needed first.

Only cancellable while status = "activation_requested". Once ops has submitted the request to the carrier, this returns 409 naming the current status — contact support instead. Cancelling atomically releases any KYC-pool passport draw and rolls the SIM's activation status back to Inactive, so it becomes resubmittable.

No open (in-flight) activation for this ICCID under your account — whether it doesn't exist, belongs to another partner, or was never submitted — 404 (existence is never leaked).

Parameters

NameInTypeDescription
iccid*pathstring

Request bodyapplication/json

Responses

200Activation cancelled
401
404
409Not cancellable — activation is no longer 'activation_requested'
429
PATCH/api/v1/activations/by-iccid/{iccid}requires auth

Reschedule an activation request, looked up by ICCID

Same guarded-update core as PATCH /api/v1/activations/{id} — for callers (e.g. ICC's automation) that hold the ICCID rather than our internal activation id. At least one of requested_activation_date / note is required.

Only editable while status = "activation_requested". Once ops has submitted the request to the carrier (or it has moved past that state for any other reason), this returns 409 naming the current status. No KYC or customer fields can be changed here.

No open (in-flight) activation for this ICCID under your account — whether it doesn't exist, belongs to another partner, or was never submitted — 404 (existence is never leaked).

Parameters

NameInTypeDescription
iccid*pathstring

Request body*application/json

Responses

200Activation rescheduled
400Validation error (no editable field, or a bad date)
401
404
409Not editable — activation is no longer 'activation_requested'
429
POST/api/v1/activations/bulk/cancelrequires auth

Cancel a batch of activation requests

Cancel up to 200 activation requests in one call. Each item is cancelled through the same atomic core as the single-cancel endpoint (POST /api/v1/activations/{id}/cancel) — one item's failure never touches the others.

Identify items with activation_ids (our internal UUIDs), iccids (for callers like ICC's automation that hold ICCIDs instead), or a mix of both — combined, up to 200. ICCIDs are resolved to their in-flight activation internally; outcomes are keyed by whichever identifier you supplied for that item (activation_id or iccid).

Partial success is normal and returns 200. Ids/ICCIDs that don't exist, don't belong to your account, or (for an ICCID) have no open activation, come back as an outcome with reason: "not_found" rather than failing the whole batch. Items that are no longer activation_requested come back as reason: "not_cancellable:<status>".

Request body*application/json

Responses

200Batch processed (see per-id outcomes; partial success is normal)
400Validation error
401
422Partner not provisioned (no agent record)
429
POST/api/v1/activations/bulk/reschedulerequires auth

Reschedule a batch of activation requests

Edit the requested activation date and/or note on up to 200 activation requests in one call. Each item identifies its activation with EXACTLY ONE of activation_id (our internal UUID) or iccid (for callers like ICC's automation that hold ICCIDs instead), needs at least one of requested_activation_date / note, and is applied through its own guarded update — one item's failure never touches the others. Each outcome is keyed by whichever identifier the item supplied.

Partial success is normal and returns 200. Ids/ICCIDs that don't exist, don't belong to your account, or (for an ICCID) have no open activation, come back as an outcome with reason: "not_found". Items that are no longer activation_requested come back as reason: "not_editable:<status>" — the same "requested-only" gate used everywhere else in the activation lifecycle.

Request body*application/json

Responses

200Batch processed (see per-id outcomes; partial success is normal)
400Validation error
401
422Partner not provisioned (no agent record)
429

KYC

Passport / KYC pool management

GET/api/v1/kyc/passportsrequires auth

List your KYC pool passports

List the passports in your own KYC pool. Returns only the fields you submitted plus a neutral outward status of received — our internal verification and usage state is never exposed. Withdrawn (soft-deleted) records are excluded.

Parameters

NameInTypeDescription
limitqueryinteger

Responses

200Passport list
401
429
POST/api/v1/kyc/passportsrequires auth

Import passports into your KYC pool

Bulk-add passports into your own KYC pool (up to 200 per request). The pool is what the activation flow draws from when a bulk activation line carries no inline passport.

Imported passports are UNVERIFIED. Each record is stored with verification_status = "pending". Our operations team must verify a passport before the auto-draw will assign it to an activation — the draw only selects verified (onshore) records. Importing here is not a substitute for KYC verification.

Records are pinned to your own partner account; you can only write into your own pool. Duplicate passport numbers — whether already in your pool or repeated within the same request — are skipped (see skipped_duplicates).

Request body*application/json

Responses

201Passports imported (unverified)
400Validation error
401
422Partner not provisioned (no agent record)
429
PATCH/api/v1/kyc/passports/{id}requires auth

Edit a KYC pool passport

Edit one of your pool passports. Only allowed while the passport has never been used for an activation — once used it is locked and must be changed by our operations team (409 Passport In Use). Editing identity fields (passport number, name, expiry) resets our verification, so the record must be re-verified before it can be drawn again.

Parameters

NameInTypeDescription
id*pathstring · uuid

Request body*application/json

Responses

200Passport updated
400Validation error
401
404
409Passport already used (locked) or number conflict
429
DELETE/api/v1/kyc/passports/{id}requires auth

Withdraw (soft-delete) a KYC pool passport

Withdraw one of your pool passports. This is a soft delete — the record leaves your pool but is retained for compliance; it is never physically deleted. Only allowed while the passport has never been used for an activation — once used it is locked (409 Passport In Use) and must be handled by our operations team.

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Passport withdrawn
401
404
409Passport already used (locked)
429

eSIMs

eSIM status and delivery

GET/api/v1/orders/{id}/esimsrequires auth

Get eSIMs for an order

Returns eSIM delivery details (ICCID, activation code, QR code URL) for a fulfilled order.

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200eSIM delivery details
400Order not yet fulfilled
401
404
GET/api/v1/esims/{iccid}/statusrequires auth

Get eSIM status

Check the activation status, data usage, and location of an eSIM by ICCID.

Parameters

NameInTypeDescription
iccid*pathstringICCID (19-20 digits)

Responses

200eSIM status
400Invalid ICCID format
401
403Not authorized to access this eSIM
404

Inventory

Product availability

GET/api/v1/inventory/statusrequires auth

Check product availability

Check real-time stock and availability status for products.

Parameters

NameInTypeDescription
product_idsquerystringComma-separated product UUIDs
skusquerystringComma-separated SKU codes
regionquerystringFilter by region

Responses

200Inventory status
401

Webhooks

Event notifications via HTTP POST to your registered endpoint. Supported events: `order.created`, `order.fulfilled`, `order.cancelled`, `esim.activated`, `esim.expired`, `payment.completed`, `payment.failed`, `activation.submitted`, `activation.confirmed`, `activation.activated`, `activation.failed` Webhook signature: `X-Webhook-Signature: t=<timestamp>,v1=<hmac_sha256_signature>`

GET/api/v1/webhooksrequires auth

List webhooks

Parameters

NameInTypeDescription
limitqueryinteger
cursorquerystring
statusqueryenum
environmentqueryenum

Responses

200Webhook list
401
POST/api/v1/webhooksrequires auth

Create webhook

Register a webhook endpoint to receive event notifications. The signing secret is returned only once in the response — store it securely.

Request body*application/json

Responses

201Webhook created with signing secret
400Validation error
401
GET/api/v1/webhooks/{id}requires auth

Get webhook details

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

200Webhook details
401
404
DELETE/api/v1/webhooks/{id}requires auth

Delete webhook

Parameters

NameInTypeDescription
id*pathstring · uuid

Responses

204Webhook deleted
401
404

Catalog

E-commerce catalog sync

GET/api/v1/catalog/syncrequires auth

Get product catalog for e-commerce

Export product catalog formatted for Shopify, WooCommerce, or generic use. Includes suggested retail pricing with configurable markup.

Parameters

NameInTypeDescription
formatqueryenum
include_imagesqueryenum
regionquerystring
typequerystring
markupquerynumberMarkup percentage for suggested retail price

Responses

200Product catalog
401

Wallet

GET/api/v1/balancerequires auth

Get wallet balance

Current pre-funded wallet balance per currency. Orders are charged in the product's currency, so the matching wallet must be funded.

Responses

200Wallet balances
401
429