Global Starlink — Partner API Guide
Integration guide for partner engineers
This guide covers everything you need to integrate with the Global Starlink Partner API: authenticating, submitting SIM activations in bulk, managing your KYC passport pool, and cancelling or rescheduling activations you've already submitted.
- Base URL:
https://api.gstarlink.com - Auth: OAuth 2.0 client credentials → short-lived bearer token. Submitting/changing needs
write:orders; reading needsread:orders; retrieving eSIM QR / LPA needsread:esims. - Format: JSON request/response; errors are RFC 7807
application/problem+jsonwith a machine-readable code. - Everything is scoped to your own account. You can only ever read or change your own passports and your own activations — another partner's records return
404. - You send the ICCID; we detect the carrier. You never specify the carrier — all products use the same activation flow, submitted and tracked the same way.
- KYC is a shared responsibility. Some Australian carriers require a passport to register a SIM. You either include the passport on the line, or keep verified passports in your KYC pool for us to draw from automatically. If a KYC-required line has neither, it is still accepted but held as
pending_no_passportuntil a passport is provided — so keep your pool stocked. See KYC passport pool.
Sandbox first. Your first API key is issued in sandbox mode. Run the full flow against it, confirm the outcomes look right, then we switch you to a production key. The base URL and request shapes are identical in both.
1. Authenticate
Exchange your client_id / client_secret for an access token.
curl -X POST https://api.gstarlink.com/api/v1/oauth/token \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"scope": "write:orders read:orders"
}'
Response (200):
{
"access_token": "eyJhbGciOiJ...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "write:orders read:orders"
}
- The token is a JWT, valid for 1 hour (
expires_in: 3600). Cache it and reuse it; request a new one when it expires. - Scopes: submitting activations needs
write:orders; reading activation status needsread:orders; retrieving eSIM QR / LPA needsread:esims. You can omitscopeto receive every scope your key was granted (request"write:orders read:orders read:esims"to cover the full flow). - Send the token on every subsequent request as
Authorization: Bearer <access_token>.
2. Submitting activations
2.1 Preflight — dry-run a batch (no changes)
Always call preflight before submitting. It runs the exact same checks as a real submission but writes nothing, so you can see, per card, whether it will be accepted and how KYC will be handled.
curl -X POST https://api.gstarlink.com/api/v1/activations/bulk/preflight \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"requested_activation_date": "2026-08-20",
"lines": [
{ "iccid": "8961030000334077256" },
{ "iccid": "001OEVY6Y" }
]
}'
Response (200):
{
"outcomes": [
{ "line_no": 1, "iccid": "8961030000334077256", "status": "accepted", "kyc": "pool" },
{ "line_no": 2, "iccid": "001OEVY6Y", "status": "accepted", "kyc": "pending_no_passport" }
],
"pool_available": 12
}
pool_available— how many verified passports are currently available in your KYC pool.- One
outcomeper line — see Outcome reference for every field and value.
2.2 Submit the batch
Same request body as preflight, sent to the /bulk endpoint. This creates the activations.
curl -X POST https://api.gstarlink.com/api/v1/activations/bulk \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"requested_activation_date": "2026-08-20",
"partner_reference": "ICC-2026-0088",
"lines": [
{ "iccid": "8961030000334077256" },
{ "iccid": "001OEVY6Y" }
]
}'
Response (201):
{
"batch_id": "b1d2c3e4-...",
"batch_number": "BA-20260820-01",
"partner_reference": "ICC-2026-0088",
"created": 2,
"kyc_pending": 1,
"outcomes": [
{ "line_no": 1, "iccid": "8961030000334077256", "status": "accepted", "kyc": "pool" },
{ "line_no": 2, "iccid": "001OEVY6Y", "status": "accepted", "kyc": "pending_no_passport" }
]
}
batch_id/batch_number— keep these to reference the batch.created— how many activation requests were created.kyc_pending— how many were accepted but still need a passport (see KYC passport pool).- The response header
Locationpoints to the batch.
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
lines | array | yes | 1–200 items |
lines[].iccid | string | yes | ICCID or activation code, 8–22 letters/digits |
requested_activation_date | string | yes* | YYYY-MM-DD, applies to the whole batch |
lines[].activation_date | string | no* | YYYY-MM-DD, overrides the batch date for this one line |
partner_reference | string | no | your own reference for this batch (max 200 chars); stored and echoed back in the response so you can reconcile against your internal batch/order id |
note | string | no | max 500 chars |
urgent | boolean | no | defaults to false |
| KYC fields (per line) | string | no | see KYC passport pool |
Your own batch reference.
batch_number(e.g.BA-20260820-01) is assigned by us; you can't set it. To tag a batch with your id, sendpartner_reference— we store it and return it in the response, so both sides can match the same batch.
* An activation date is required for every line. Supply it once for the whole batch via
requested_activation_date, or per line vialines[].activation_date(which overrides the batch date). If a line has neither, it is rejected with reasonmissing_activation_date— a card can't be activated without a date. The date must be today or later (in Australia/Sydney time).
Card identifier.
iccidaccepts a numeric ICCID or an alphanumeric activation code (e.g. TeleChoice001OEVY6Y) — any 8–22 letters/digits. Send exactly what's printed on the card. A value we don't recognise in your inventory comes back asnot_found; a malformed value comes back asbad_format.
2.3 Check activation status
Poll by ICCID (list) or by request id (detail).
By ICCID:
curl "https://api.gstarlink.com/api/v1/activations?iccid=8961030000334077256" \
-H "Authorization: Bearer <access_token>"
{
"data": [
{
"id": "a1b2...",
"iccid": "8961030000334077256",
"carrier": "Optus",
"activation_date": "2026-08-20",
"customer_name": "Jane Doe",
"status": "activated",
"processing_status": "completed",
"mobile_number": "04xxxxxxxx",
"confirmation_number": "...",
"created_at": "...",
"updated_at": "..."
}
],
"count": 1
}
By request id: GET /api/v1/activations/{id} returns the same fields plus carrier_region, plan_name, note, error_type, error_message.
Status values you'll see (status):
| Status | Meaning |
|---|---|
activation_requested | received, queued for processing |
pending / urgent_pending | awaiting processing |
processing | being worked |
activated / completed / active | live — mobile_number is populated when available |
failed / rejected | did not activate (error_message explains) |
cancelled | cancelled |
expired | activation window passed |
All products use the same activation flow — submit the request, then poll here until the card reaches a terminal status. How each carrier is processed on our side does not change anything you do.
Polling cadence. Activation is not instant — we process it (and for some carriers the SIM is activated by our operations team) after you submit, so there is a delay before the result is ready. Poll this endpoint on an interval (e.g. every 1–5 minutes) until each card reaches a terminal status (activated / failed / cancelled). When status is activated: physical-SIM results carry the mobile_number; eSIM results are retrieved as a QR / LPA in the next step.
2.4 Retrieve the eSIM QR / LPA (eSIM products)
For eSIM products the QR code and LPA string are generated when the card is activated (for TeleChoice, only after activation completes). Query directly by ICCID — needs the read:esims scope:
curl "https://api.gstarlink.com/api/v1/esims/{iccid}/status" \
-H "Authorization: Bearer <access_token>"
Response (200):
{
"iccid": "8961030000334077256",
"status": "active",
"activation_code": "LPA:1$smdp.gstarlink.com$K2-1A2B3C-4D5E6F",
"qr_code_url": "https://api.gstarlink.com/api/v1/esims/8961030000334077256/qr",
"smdp_address": "smdp.gstarlink.com",
"activated_at": "2026-08-20T02:15:00Z",
"expires_at": "2026-09-19T02:15:00Z",
"product": { "name": "Telechoice 60GB", "sku": "eSIM-AU-TC-01", "validity_days": 30 }
}
activation_code— the LPA string to install the eSIM (formatLPA:1$<smdp>$<code>). This is the value your customer's phone needs.qr_code_url— a ready-to-render QR image encoding that same LPA.smdp_address— the SM-DP+ server, if you generate your own QR.- Before activation,
statusisinactiveandactivation_code/qr_code_urlarenull— poll untilstatusisactive, then read the credentials.
One endpoint, by ICCID.
GET /api/v1/esims/{iccid}/statusreturns both the live status and the QR / LPA once ready — so for eSIM you can poll this single endpoint by ICCID untilstatusisactive, no order id needed. (The activation-status endpoint in step 2.3 stays useful for the request lifecycle and, for physical SIMs, themobile_number.)To pull every eSIM in one order at once,
GET /api/v1/orders/{order_id}/esimsreturns the sameactivation_code/qr_code_urlfor each card.
Prefer push over polling? Subscribe to webhooks and we notify your endpoint the moment an activation finishes — see 9. Webhooks. Webhooks and polling can be used together; the polling flow above always remains available as a fallback.
Outcome reference
Every line in a preflight or submit response is one outcome:
| Field | Type | Meaning |
|---|---|---|
line_no | number | 1-based index matching your lines array |
iccid | string | the card, echoed back |
status | "accepted" | "rejected" | whether the line was taken |
reason | string | rejected only — why (table below) |
kyc | string | accepted only — how KYC was handled (table below) |
reason (rejected lines):
| Reason | Meaning — what to do |
|---|---|
not_your_sim | This card isn't in your inventory. Check the number. |
not_found | We don't recognise this card at all. Check for typos. |
already_active | The card is already activated — nothing to do. |
duplicate_in_flight | An activation for this card is already in progress. |
bad_format | Not a valid identifier (must be 8–22 letters/digits). |
bad_activation_date | The activation date is invalid or in the past. |
missing_activation_date | No activation date supplied for this line or batch. |
no_partner_link | Ownership couldn't be resolved — contact us. |
kyc (accepted lines):
| Value | Meaning |
|---|---|
none | This product doesn't require KYC. |
inline | You supplied the passport details on the line; we'll use them. |
pool | You didn't supply a passport; we drew a verified one from your KYC pool. |
pending_no_passport | KYC is required but your pool was empty — accepted anyway, held until a passport is added. |
3. KYC passport pool
Some Australian carriers require an identity (passport) to register a SIM. You have two options per line:
- Send the passport inline — include the fields below on the line. We use them as-is.
- Send nothing — we automatically draw a verified passport from your KYC pool (passports you've uploaded and we've confirmed as onshore in Australia).
If KYC is required and neither is available, the line is still accepted (never rejected) and held as pending_no_passport until a passport is provided.
Optional per-line KYC fields:
| Field | Format |
|---|---|
first_name | string |
last_name | string |
date_of_birth | YYYY-MM-DD |
passport_no | string |
passport_country | string |
passport_expiry_date | YYYY-MM-DD |
A passport may be registered up to 4 times per carrier (each carrier counts separately). We manage that limit for you when drawing from the pool.
The KYC pool is your store of passports. When you submit a KYC-required activation without a passport on the line, we automatically draw a verified passport from your pool. Keeping the pool stocked means fewer lines held as pending_no_passport.
Imported passports start UNVERIFIED. Every passport you add via the API is stored with
verification_status: "pending". Our operations team verifies it before the auto-draw will use it — importing here is not a substitute for our KYC review. Keep this in mind for timing: import ahead of when you need them.
3.1 Import passports
POST /api/v1/kyc/passports — add up to 200 passports in one call. Duplicates (same passport number already in your pool, or repeated within the request) are skipped.
curl -X POST https://api.gstarlink.com/api/v1/kyc/passports \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{
"records": [
{
"title": "Mr",
"first_name": "Alice",
"last_name": "Traveller",
"date_of_birth": "1990-01-01",
"passport_no": "X1234567",
"passport_country": "GB",
"passport_expiry_date": "2030-01-01"
}
],
"group_label": "2026-q3-batch"
}'
Response (201):
{ "ok": true, "created": 1, "skipped_duplicates": 0, "verification_status": "pending" }
- Required per record:
first_name,last_name,passport_no. Others are optional. - Dates are literal calendar dates,
YYYY-MM-DD.group_labelis an optional tag for your own reconciliation.
3.2 List your pool
GET /api/v1/kyc/passports — returns the passports you submitted, plus a neutral status of received. Withdrawn records are excluded. Scope: read:orders.
curl https://api.gstarlink.com/api/v1/kyc/passports?limit=100 \
-H "Authorization: Bearer <access_token>"
{ "records": [
{ "id": "…uuid…", "first_name": "Alice", "last_name": "Traveller",
"passport_no": "X1234567", "passport_country": "GB",
"passport_expiry_date": "2030-01-01", "group_label": "2026-q3-batch",
"status": "received" }
], "count": 1 }
The response returns only the data you submitted. Our internal verification state and usage counts are never exposed.
statusis alwaysreceivedfor a passport that is in your pool.
3.3 Edit a passport
PATCH /api/v1/kyc/passports/{id} — correct a passport's details. Send any subset of the editable fields.
curl -X PATCH https://api.gstarlink.com/api/v1/kyc/passports/<id> \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "passport_expiry_date": "2031-05-01" }'
- Only allowed while the passport has never been used for an activation. Once it has been drawn for an activation it is locked — you get
409 Passport In Useand must contact support. - Changing an identity field (passport number, name, expiry) resets our verification — the passport must be re-verified before it can be drawn again.
3.4 Withdraw a passport
DELETE /api/v1/kyc/passports/{id} — remove an unused passport from your pool. This is a soft delete: the record is retained for compliance, never physically erased.
curl -X DELETE https://api.gstarlink.com/api/v1/kyc/passports/<id> \
-H "Authorization: Bearer <access_token>"
{ "ok": true, "id": "…uuid…", "status": "withdrawn" }
As with editing, this is only allowed while the passport has never been used (else 409 Passport In Use).
4. Cancel & reschedule
The one rule that governs both. You may cancel or reschedule an activation only while it is still
activation_requested— i.e. before our team has submitted it to the carrier. Once it moves past that (submitted / processing), it is locked and you get409; from then on it must be handled by our operations team.
You can address an activation by its ICCID (recommended — you already have it) or by the activation id returned when you look it up. Both single and batch are supported.
4.1 Cancel — single
By ICCID: POST /api/v1/activations/by-iccid/{iccid}/cancel
curl -X POST https://api.gstarlink.com/api/v1/activations/by-iccid/8961030000334077256/cancel \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "reason": "customer changed their mind" }'
{ "ok": true, "iccid": "8961030000334077256", "activation_id": "…", "status": "cancelled" }
By activation id: POST /api/v1/activations/{id}/cancel (same body/response, keyed by id).
- Cancelling frees the SIM: it returns to your inventory as inactive, ready to be submitted again (for the same or a new customer).
- Not cancellable (already submitted to carrier) →
409. No open activation for that ICCID →404.
4.2 Cancel — batch
POST /api/v1/activations/bulk/cancel — up to 200 per call. Provide iccids, or activation_ids, or both.
curl -X POST https://api.gstarlink.com/api/v1/activations/bulk/cancel \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "iccids": ["8961030000334077256", "8961030000334077257"], "reason": "batch recalled" }'
{ "cancelled": 1, "errors": 1, "outcomes": [
{ "iccid": "8961030000334077256", "status": "cancelled" },
{ "iccid": "8961030000334077257", "status": "error", "reason": "not_cancellable:processing" }
] }
Partial success is normal — each item reports its own outcome (cancelled, or error with a reason such as not_found or not_cancellable:<status>).
4.3 Reschedule — single
Change the activation date (and/or note). By ICCID: PATCH /api/v1/activations/by-iccid/{iccid}
curl -X PATCH https://api.gstarlink.com/api/v1/activations/by-iccid/8961030000334077256 \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "requested_activation_date": "2026-09-15" }'
{ "ok": true, "iccid": "8961030000334077256", "activation_id": "…" }
By activation id: PATCH /api/v1/activations/{id} (same body, keyed by id).
- Only the activation date and note are editable — customer/KYC details are not. Same
activation_requested-only rule (else409).
4.4 Reschedule — batch
POST /api/v1/activations/bulk/reschedule — up to 200 items. Each item is keyed by iccid or activation_id, with the new date and/or note.
curl -X POST https://api.gstarlink.com/api/v1/activations/bulk/reschedule \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" \
-d '{ "items": [
{ "iccid": "8961030000334077256", "requested_activation_date": "2026-09-15" },
{ "iccid": "8961030000334077257", "requested_activation_date": "2026-09-20", "note": "hold for pickup" }
] }'
{ "updated": 2, "errors": 0, "outcomes": [
{ "iccid": "8961030000334077256", "status": "updated" },
{ "iccid": "8961030000334077257", "status": "updated" }
] }
5. Changing the customer on an activation
There is no endpoint to change the customer/KYC details on an existing activation. If the customer details are wrong, or the SIM is going to a different customer, the flow is:
- Cancel the activation (Cancel & reschedule) — this frees the SIM back to inactive.
- Submit a new activation for that SIM with the correct/new customer details (see Submitting activations).
Rescheduling (changing the date) keeps the same activation; changing the customer is a fresh submission.
6. Errors
All errors (except the token endpoint) use RFC 7807 application/problem+json. Branch on the machine-readable code (or the per-item reason in batch responses), not on the human text.
{
"type": "https://docs.gstarlink.com/errors/validation",
"title": "Validation Error",
"status": 400,
"detail": "lines: array must contain at least 1 element(s)",
"errors": { "lines": ["array must contain at least 1 element(s)"] }
}
| Status | When |
|---|---|
400 | Malformed JSON, or request failed validation (errors lists the fields). |
401 | Missing / invalid / expired token — re-authenticate. |
403 | Your key lacks the required scope, or the account is suspended. |
422 | Your partner account isn't fully provisioned — contact us. |
429 | Rate limit hit — back off and retry after Retry-After. |
500 | Unexpected error on our side — safe to retry. |
The OAuth token endpoint uses the OAuth error shape instead:
{ "error": "invalid_client", "error_description": "Invalid client credentials" }
Common values: invalid_request, invalid_client, invalid_scope, unauthorized_client, rate_limited.
Cancel / reschedule / KYC pool error codes and reasons:
| Code / reason | Meaning |
|---|---|
not_cancellable:<status> | Activation is past activation_requested (already with the carrier). Contact ops. |
not_editable:<status> | Reschedule refused for the same reason. |
passport_in_use | Passport already used for an activation; edit/withdraw is locked. |
passport_conflict | A passport with that number already exists in your pool. |
not_found / 404 | No such record in your account (also returned for another partner's record — no existence is leaked). |
429 | Rate limited — retry after a short back-off. |
7. Rate limits
| Scope | Limit |
|---|---|
| Activation endpoints (bulk, preflight, single, status) | 60 requests / minute per partner |
| Token endpoint | 20 requests / minute per IP |
| Failed logins | 5 / 15 minutes per IP |
Activation responses include X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset; a 429 includes Retry-After (seconds). Prefer batched submissions (up to 200 cards per call) over many single calls.
8. Recommended flow
- Get a token (cache for ~55 minutes).
- Preflight your batch → fix any
rejectedlines, confirm KYC handling. - Submit the batch → store
batch_id/batch_number. - Poll status by ICCID every 1–5 min until each card reaches a terminal status (
activated/failed/cancelled). - Once
activated: read themobile_number(physical SIM), or fetch the eSIM QR / LPA by ICCID viaGET /api/v1/esims/{iccid}/status(eSIM). - Keep your KYC pool stocked — import passports ahead of time; allow for our verification step before they auto-draw.
- Need to move a date? Reschedule — same activation, cheapest change.
- Need to change the customer, or drop the order? Cancel (frees the SIM), then re-submit if needed.
- Prefer working by ICCID — every operation accepts it, so you never need to track our internal ids.
(Prefer push? Subscribe to webhooks (9. Webhooks) and steps 4–5 are replaced by a single push to your endpoint — the polling flow stays available as a fallback.)
9. Webhooks
Instead of polling, you can have us push the activation result to your own HTTPS endpoint the moment it's ready. To turn this on, send us (1) your HTTPS URL and (2) the events you want. We reply with a signing secret — keep it private; it's how you verify each delivery really came from us.
Events:
| Event | Fires when |
|---|---|
activation.activated | An activation you submitted has gone live. Physical SIM carries the mobile_number; eSIM carries the QR / LPA. |
activation.failed | An activation reached a genuine dead end (e.g. the carrier rejected it). Carries an error_message. |
Delivery envelope — every webhook POST body looks like this; the event-specific fields are under data:
{
"event": "activation.activated",
"event_id": "evt_9f2c1a7b3d",
"timestamp": "2026-08-20T02:15:00Z",
"webhook_id": "wh_1a2b3c",
"data": { }
}
activation.activated — physical SIM:
{
"activation_id": "act_7b3d9f2c1a",
"iccid": "8961030000334077256",
"carrier": "TeleChoice",
"status": "active",
"activation_date": "2026-08-20",
"mobile_number": "+61400000000",
"esim": null,
"activated_at": "2026-08-20T02:15:00Z"
}
activation.activated — eSIM (mobile_number is null; the QR / LPA is under esim):
{
"activation_id": "act_7b3d9f2c1a",
"iccid": "8961030000334077256",
"carrier": "TeleChoice",
"status": "active",
"activation_date": "2026-08-20",
"mobile_number": null,
"esim": {
"activation_code": "LPA:1$smdp.gstarlink.com$K2-1A2B3C-4D5E6F",
"qr_code_url": "https://api.gstarlink.com/api/v1/esims/8961030000334077256/qr",
"smdp_address": "smdp.gstarlink.com"
},
"activated_at": "2026-08-20T02:15:00Z"
}
activation.failed:
{
"activation_id": "act_7b3d9f2c1a",
"iccid": "8961030000334077256",
"carrier": "TeleChoice",
"status": "failed",
"error_message": "Carrier rejected the identity document",
"failed_at": "2026-08-20T02:15:00Z"
}
Treat deliveries as "latest wins" by
activation_id. A card is sometimes marked activated a moment before its mobile number (or eSIM QR / LPA) is recorded on our side. When that happens you'll receiveactivation.activatedwith those fieldsnull, then a secondactivation.activatedfor the sameactivation_idonce they're filled in. Upsert onactivation_idand take the newest payload — never assume the first delivery is final, and don't treat the pair as two different cards.
Verify every delivery. Each request carries a signature header:
X-Webhook-Event: activation.activated
X-Webhook-ID: evt_9f2c1a7b3d
X-Webhook-Signature: t=1755654900,v1=<hex-hmac>
Recompute the signature and compare before trusting the body:
- Read
t(unix seconds) andv1fromX-Webhook-Signature. - Compute
HMAC-SHA256( secret, "<t>." + rawRequestBody )as lowercase hex — note the literal.between the timestamp and the exact raw body bytes (sign before any JSON re-serialisation). - Reject if it doesn't equal
v1, or iftis more than 5 minutes from your clock (replay protection).
// Node.js
const crypto = require('crypto');
function verify(rawBody, header, secret) {
const [tPart, v1Part] = header.split(',');
const t = tPart.split('=')[1];
const expected = v1Part.split('=')[1];
const mac = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(expected));
return ok && Math.abs(Date.now() / 1000 - Number(t)) < 300;
}
Acknowledge & retries. Respond 2xx quickly to acknowledge — do your heavy work asynchronously. If we don't get a 2xx we retry with exponential backoff (up to 5 attempts). After repeated consecutive failures the subscription is auto-disabled and we'll contact you. Deliveries are at-least-once, so make your handler idempotent (dedupe on event_id for exact repeats, and reconcile on activation_id per the note above).
Appendix — single-card endpoint
If you ever need to submit one card on its own, POST /api/v1/activations takes a single iccid + activation_date (plus KYC fields, which become required for KYC carriers) and returns one activation object. The bulk endpoint handles a single card equally well (just one item in lines), so most integrations only need the bulk flow above.
Questions? Contact your Global Starlink integration contact.