Overview
This page is for operators who want to work with GrabJet. If you do not have your own software, you can use the GrabJet operator portal. If you already manage aircraft, availability, or dispatch in another tool, you can connect by webhook or API after onboarding.
This page is intentionally focused on small operators using GrabJet's simple API or webhook flow.
Quickstart
If you are a local operator, start here. You can become operational in GrabJet through the portal first, then add API/webhook automation only when your team is ready.
| Step | Action |
|---|---|
| 1. Apply | Submit the operator request from the public site or contact GrabJet partnerships. |
| 2. Get approved | GrabJet verifies company, certificate, fleet, documents, and operating contacts. |
| 3. Start portal-first | Use the operator portal for fleet, routes, bookings, empty legs, and payouts. |
| 4. Choose automation | If needed, choose API key or signed webhooks. |
| 5. Test in sandbox | Send sample payloads, confirm idempotency, and complete booking round-trip checks. |
| 6. Go live | Enable production after business, operations, finance, and security sign-off. |
Example API request after sandbox access
Use whichever stack your operator system already uses. These examples all send the same aircraft update payload.
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/aircraft" \
-H "Content-Type: application/json" \
-H "X-API-Key: gj_sandbox_..." \
-H "Idempotency-Key: evt_aircraft_1001" \
-H "X-GrabJet-Event: aircraft.updated" \
-d @aircraft.updated.jsonDeveloper Build Checklist
If your operator system is ready to integrate, use this order. It covers what you send to GrabJet, what GrabJet sends back, and what your admin reviewer needs before production access.
| Step | What To Build / Verify |
|---|---|
| 1. Store credentials | Put GRABJET_BASE_URL, GRABJET_OPERATOR_ID, GRABJET_API_KEY, and GRABJET_WEBHOOK_SECRET in server-side env/secret storage. |
| 2. Pick enabled modules | Start with aircraft, availability, booking response, flight status, and documents. Add pricing, crew, maintenance, dispatch, payout, and notifications as needed. |
| 3. Implement inbound sender | POST JSON to the module endpoint with X-API-Key, X-GrabJet-Event, Idempotency-Key, and Content-Type: application/json. |
| 4. Implement outbound receiver | Expose an HTTPS webhook endpoint, verify X-GrabJet-Signature, queue the event, return 2xx quickly, and dedupe by event_id. |
| 5. Send first sandbox data | Send aircraft.updated, availability.updated, booking.accepted/rejected, flight.status_changed, and document.updated using the examples below. |
| 6. Test duplicates and errors | Replay the same Idempotency-Key, send one invalid payload, and confirm GrabJet returns safe duplicate or validation errors without core side effects. |
| 7. Test replay safety | Replay the same payload with the same idempotency key and confirm GrabJet safely handles duplicates. |
| 8. Review in portal | Check Integration Status for what GrabJet received, what GrabJet sent, failed retries, and next action. |
| 9. Save your test notes | Keep request IDs, staging/apply results, and retry proof so your admin reviewer can confirm sandbox worked. |
Environments
GrabJet issues sandbox access before production access. Production credentials are issued only after sandbox testing and admin review are complete.
| Environment | Purpose | Access |
|---|---|---|
| Sandbox | Used for onboarding, payload validation, webhook tests, and booking round-trip checks. | Issued after operator approval |
| Production | Used after admin confirms sandbox worked and issues live credentials. | Issued after final approval |
Supported Sync Data
The operator integration service supports intake, authentication, idempotency, normalization, validation, staging, and review for all data areas below. Valid records can then be reviewed and applied through GrabJet's controlled core-service workflow.
| Data Area | Direction | Supported Fields / Signals |
|---|---|---|
| Aircraft | Operator to GrabJet | tail number, type, seats, range, airport, readiness, documents |
| Crew | Operator to GrabJet | pilot identity, license, medical, duty availability |
| Availability | Two-way | availability windows, booked holds, conflicts, manual review |
| Pricing | Operator to GrabJet | hourly rates, route pricing, reposition policy, fees |
| Maintenance | Operator to GrabJet | grounded state, release status, MEL/CDL restrictions |
| Booking | GrabJet to Operator | booking request, accept/reject, cancel, dispatch state |
| Empty Legs | Two-way | opportunity, publish/hide state, booking state, linked parent booking |
| Flight Status | Operator to GrabJet | scheduled, taxi, airborne, landed, delayed, cancelled |
| Dispatch / Compliance | Two-way visibility | dispatch ready/blocked, permit/compliance, readiness signals |
| Finance / Payout | GrabJet source of truth | payment and payout visibility |
| Notifications / Webhooks | Two-way visibility | booking, dispatch, payout, and flight status event notifications |
Connection Model
Operators do not need to choose only one integration style. GrabJet supports a practical hybrid model: portal for human workflows, API for direct pushes, inbound webhooks for operator events, and outbound webhooks for GrabJet events sent back to the operator.
| Channel | Used By | Best For | Developer Notes |
|---|---|---|---|
| Portal | Operator users | Manual operations | Best first step for local operators that do not need automation yet. |
| REST API | Operator system | Server-to-server sync | Good for scheduled or on-change updates from an internal operator system. |
| Inbound webhook | Operator system | Event-driven sync | Good for critical events like grounded aircraft, availability changes, and flight status. |
| Outbound webhook | GrabJet | GrabJet-to-operator events | Used for booking requests, cancellation, dispatch readiness, empty-leg, payout, and retry visibility. |
Staging, Review & Apply
Third-party data never writes straight into GrabJet's core aircraft, booking, dispatch, payout, or customer-facing systems. Every external event first passes through staging, validation, conflict checks, and audit. This protects both the operator and GrabJet from bad payloads, duplicate events, and booking conflicts.
| Stage | What Happens |
|---|---|
| 1. Receive | GrabJet receives API or webhook data with auth, signature, rate-limit, and idempotency checks. |
| 2. Normalize | Payload fields are mapped into GrabJet's common module model while retaining original source references. |
| 3. Validate | Required fields, enum values, dates, airport codes, and ownership rules are checked. |
| 4. Stage | The record is stored as a staged record first. It does not write directly into core booking, aircraft, payout, or dispatch systems. |
| 5. Review | Safe records can be accepted automatically or by admin review. Conflicts go to manual review. |
| 6. Apply | Accepted records are applied to core modules only through GrabJet's controlled apply workflow. |
| 7. Audit | Every decision, duplicate, rejection, conflict, apply result, and outbound delivery is traceable. |
Module Capability, Ownership & Frequency
Not every operator enables every module. During onboarding, GrabJet confirms which modules are enabled, who owns conflicts, and how often data should arrive. Critical operational events should be webhook-first; master data can usually sync on change or by schedule.
| Module | Direction | Data Ownership | Expected Frequency | Apply Rule |
|---|---|---|---|---|
| Aircraft | Operator → GrabJet | Operator wins | On change or daily | Safe auto when identity and readiness validate |
| Crew | Operator → GrabJet | Operator wins | 15-30 min or on change | Safe auto for non-conflicting readiness updates |
| Availability | Operator → GrabJet | Operator wins, conflict review | Near real-time / every few minutes | Manual review when it overlaps active bookings |
| Pricing | Operator → GrabJet | GrabJet review or operator wins by contract | Hourly or on change | Manual review before publishing where configured |
| Maintenance | Operator/provider → GrabJet | Operator/provider wins | Immediate webhook on grounded/released change | Manual review if dispatch safety is affected |
| Booking | GrabJet → Operator + response back | GrabJet booking source of truth | Instant | Accept/reject response must use idempotency |
| Dispatch | Two-way visibility | GrabJet final dispatch decision | Instant for ready/blocked | Blocked states stay visible until resolved |
| Payout | GrabJet → Operator | GrabJet finance source of truth | Event-based | Visibility only unless finance enables deeper settlement automation |
Who Should Use This
GrabJet tracks operators by origin and operating model. Some operators are created directly by GrabJet operations, some arrive through the public request flow, and local third-party operators can connect through API or signed webhook once sandbox access is issued.
| Operator Type | How It Starts | Connection Path |
|---|---|---|
| GrabJet / System Operator | Operator is created by GrabJet admin or internal operations. | Use GrabJet portal and core workflows first. Integration can be enabled later if automation is needed. |
| Frontend Request Operator | Operator starts from the public request or sandbox access form. | GrabJet reviews the request, approves onboarding, creates the operator, then issues sandbox access if automation is required. |
| Third-party Local Operator | Operator has an internal system, spreadsheet workflow, or custom local software. | Use Generic REST API or signed webhooks. Data is staged first, reviewed/applied, then visible in GrabJet core modules. |
Before You Apply
Prepare these items before onboarding. Some fields can be completed later, but faster verification depends on clear company, fleet, document, and operations data.
| Requirement | What GrabJet Needs |
|---|---|
| Company identity | Legal company name, country, operating region, registration number, and primary contact. |
| Operating authority | AOC/operating certificate, regulatory authority, expiry date, and relevant document copies. |
| Fleet basics | Aircraft tail numbers, aircraft type, seats, range, base airport, documents, and readiness status. |
| Commercial setup | Routes, empty-leg preferences, pricing policy, payout details, and invoice contact. |
| Operations contact | 24/7 dispatch or operations contact for booking acceptance, delays, cancellation, or urgent issue handling. |
| Technical contact | Only required if you want API/webhook automation. |
Onboarding
- 1Submit the operator application or contact the GrabJet partnership team.
- 2GrabJet verifies company, AOC/operating certificate, documents, region, fleet, and contacts.
- 3GrabJet admin creates or approves the operator profile.
- 4Operator admin users are invited to the GrabJet operator portal.
- 5Operator adds or confirms aircraft, routes, empty-leg rules, payout details, and operational contacts.
- 6GrabJet reviews aircraft readiness, airport compatibility, documents, and commercial setup.
- 7Operator starts receiving and managing bookings in the portal.
- 8API/webhook automation is enabled later only if the operator needs it.
Portal Workflow
For most local operators, this is the real starting point. The portal gives the operator a full workflow without requiring any API build.
| Area | What Operator Does |
|---|---|
| 1. Profile | Maintain company profile, regulatory details, contact information, and operational support contacts. |
| 2. Fleet | Add aircraft, readiness status, range, runway needs, documents, and maintenance/grounding state. |
| 3. Routes | Create sellable routes and predefined empty-leg opportunities. |
| 4. Bookings | Review new booking requests, track approvals, and coordinate mission readiness. |
| 5. Empty Legs | Publish or manage eligible repositioning legs after the main booking flow creates them. |
| 6. Payouts | Track payout requests, status, and settlement visibility from GrabJet. |
| 7. Notifications | Receive alerts for booking, dispatch, payout, readiness, and operational exceptions. |
Authentication
For most local operators, no API is required at the beginning. GrabJet can onboard you through the operator portal first. API key and signed webhook modes are used only when your team wants automated sync.
| Mode | Use Case | Notes |
|---|---|---|
| Portal login | Operators without an internal system | Manage aircraft, routes, bookings, empty legs, payouts, and profile directly in GrabJet. |
| API key | Simple server-to-server automation | Use X-API-Key plus signed payloads. |
| Signed webhook | Event delivery into GrabJet | Use HMAC signature of raw JSON body. |
Credential Setup Guide
After sandbox approval, GrabJet issues environment-specific credentials. Keep these values server-side only. Never put API keys or webhook secrets in browser JavaScript, mobile apps, public Git repositories, screenshots, or client-side logs.
| Variable | Purpose | Example |
|---|---|---|
| GRABJET_BASE_URL | Backend gateway API base URL. | https://api.grabjet.com/ |
| GRABJET_API_KEY | API key issued by GrabJet after sandbox approval. | gj_sandbox_xxxxx |
| GRABJET_WEBHOOK_SECRET | Shared secret used to sign webhook payloads. | whsec_xxxxx |
| GRABJET_OPERATOR_ID | Your GrabJet operator ID from onboarding. | op_123 |
| GRABJET_ENV | Current environment for logs and safety checks. | sandbox |
Recommended server environment variables
# .env
GRABJET_ENV=sandbox
GRABJET_BASE_URL=https://api.grabjet.com/
GRABJET_OPERATOR_ID=op_123
GRABJET_API_KEY=gj_sandbox_...
GRABJET_WEBHOOK_SECRET=whsec_...
# Never commit these values.
# Store production credentials in a server-side secret manager.Versioning & Deprecation Policy
GrabJet keeps integration changes stable and versioned. Developers should safely ignore unknown optional fields and pin integrations to the documented API version.
| Topic | Policy |
|---|---|
| Base path | All public integration endpoints are namespaced under /api/v1. |
| Backward compatibility | GrabJet avoids breaking changes inside a stable version whenever possible. |
| Deprecation window | Breaking changes are announced with a target migration window before removal. |
| Additive changes | New optional fields may be added without a version bump. Ignore unknown fields safely. |
| Upgrade process | GrabJet will provide migration notes, examples, and sandbox validation before production cutover. |
Rate Limit Details
Sandbox limits protect the shared onboarding environment. Production limits are adjusted after expected module volume and sync frequency are reviewed.
| Rule | Details |
|---|---|
| Default sandbox limit | 60 requests per minute per API key/operator profile unless otherwise agreed. |
| Production limit | Configured per operator based on fleet size, sync modules, and expected volume. |
| Burst behavior | Short bursts may be allowed, but sustained high volume can return 429. |
| 429 response | Back off and retry. If Retry-After is present, wait that many seconds. |
| Retry safety | When retrying a write request, reuse the same Idempotency-Key. |
Required Headers
This section applies only if the operator uses API or webhook automation. Portal-only operators do not need these headers.
| Header | Description |
|---|---|
| Authorization | Bearer token only if GrabJet explicitly gives you token-based access for a custom setup. |
| X-API-Key | API key issued by GrabJet for sandbox or production. |
| X-GrabJet-Signature | HMAC signature of the raw request body. |
| Idempotency-Key | Unique key per event/request to prevent duplicate processing. |
| X-GrabJet-Event | Event name, for example aircraft.updated. |
| Content-Type | application/json |
| Convention | Rule |
|---|---|
| Format | JSON request and response bodies. |
| Timestamps | ISO 8601 UTC, for example 2026-06-29T10:30:00Z. |
| Airport codes | ICAO preferred, IATA accepted where configured. |
| Distance/range | Nautical miles for aircraft range; kilometers may be accepted only if field is explicit. |
| Money | Minor units or decimal amount must be agreed during onboarding; currency should be explicit. |
| Ids | Send both your operator_reference and GrabJet reference when available. |
Inbound APIs
Inbound endpoints are used when an operator sends data to GrabJet from its own system. These endpoints are sandbox-first and require authentication plus idempotency.
| Receive Mode | How GrabJet Handles It |
|---|---|
| REST API | Operator posts JSON payloads to module endpoints with API key, event type, and idempotency key. |
| Signed webhook | Operator sends event JSON to the generic webhook receiver with HMAC signature and duplicate-safe event_id. |
| Staging result | Valid records become ready_for_review or safe-auto candidates. Invalid records create validation errors/conflicts. |
| Method | Path | Purpose |
|---|---|---|
| POST | /api/v1/integrations/operators/{operator_id}/webhooks/{connector} | Generic signed webhook receiver for connector events. |
| POST | /api/v1/integrations/operators/{operator_id}/aircraft | Sync aircraft identity, status, readiness, and operational fields. |
| POST | /api/v1/integrations/operators/{operator_id}/crew | Sync crew identity, license, medical, duty availability, and assignment references. |
| POST | /api/v1/integrations/operators/{operator_id}/availability | Sync aircraft or route availability windows and blocks. |
| POST | /api/v1/integrations/operators/{operator_id}/pricing | Sync hourly rates, route pricing, empty-leg pricing, discounts, and fee signals. |
| POST | /api/v1/integrations/operators/{operator_id}/documents | Sync aircraft, operator, or crew document references and expiry states. |
| POST | /api/v1/integrations/operators/{operator_id}/maintenance | Sync grounded state, maintenance release, MEL/CDL restrictions, and release notes. |
| POST | /api/v1/integrations/operators/{operator_id}/bookings | Sync operator booking accept/reject/cancel status back to GrabJet. |
| POST | /api/v1/integrations/operators/{operator_id}/empty-legs | Sync empty-leg publish, hide, booked, or linked parent booking state. |
| POST | /api/v1/integrations/operators/{operator_id}/flight-status | Sync scheduled, taxi, airborne, landed, delayed, or cancelled status. |
| POST | /api/v1/integrations/operators/{operator_id}/dispatch-compliance | Sync dispatch readiness, permit/compliance, and aircraft/crew/airport readiness signals. |
| POST | /api/v1/integrations/operators/{operator_id}/finance-payouts | Sync payout or settlement visibility while GrabJet remains payment source of truth. |
| POST | /api/v1/integrations/operators/{operator_id}/notifications | Sync notification/webhook event delivery state for operator-facing events. |
Pagination / List API Pattern
Most public operator endpoints are write-first. If a future endpoint returns lists, use this standard pagination shape so client code stays consistent across API versions.
| Parameter | Meaning |
|---|---|
| page | 1-based page number. Example: page=1. |
| page_size | Number of records per page. Default and max depend on endpoint policy. |
| sort | Optional sort field, for example created_at or updated_at. |
| direction | asc or desc. |
| updated_since | Optional ISO timestamp for incremental sync where supported. |
Example paginated response
GET /api/v1/integrations/operators/op_123/sync-runs?page=1&page_size=25&direction=desc
{
"success": true,
"data": [],
"metadata": {
"total": 124,
"page": 1,
"page_size": 25,
"total_pages": 5,
"has_next": true
}
}API Examples
Every write request follows the same pattern: send JSON to the module endpoint, include your sandbox API key, include a unique idempotency key, and set the event name in X-GrabJet-Event. Use the language tab that matches your operator system.
Aircraft sync
POST /api/v1/integrations/operators/op_123/aircraftUse this when an operator system updates aircraft identity, location, readiness, documents, or MEL/CDL state.
Event: aircraft.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/aircraft" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_aircraft_1001" \
-H "X-GrabJet-Event: aircraft.updated" \
-d @aircraft.updated.jsonAvailability sync
POST /api/v1/integrations/operators/op_123/availabilityUse this when aircraft availability windows, holds, or operational blocks change.
Event: availability.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/availability" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_availability_1002" \
-H "X-GrabJet-Event: availability.updated" \
-d @availability.updated.jsonCrew sync
POST /api/v1/integrations/operators/op_123/crewUse this for pilot identity, license, medical, duty availability, and assigned aircraft updates.
Event: crew.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/crew" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_crew_1003" \
-H "X-GrabJet-Event: crew.updated" \
-d @crew.updated.jsonMaintenance / MEL-CDL sync
POST /api/v1/integrations/operators/op_123/maintenanceUse this for grounded state, maintenance release, signed release, and MEL/CDL restriction updates.
Event: maintenance.release.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/maintenance" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_maintenance_1004" \
-H "X-GrabJet-Event: maintenance.release.updated" \
-d @maintenance.release.updated.jsonPricing sync
POST /api/v1/integrations/operators/op_123/pricingUse this for hourly rates, route price, empty-leg price, discount policy, and fee signals.
Event: pricing.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/pricing" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_pricing_1005" \
-H "X-GrabJet-Event: pricing.updated" \
-d @pricing.updated.jsonBooking accept / reject
POST /api/v1/integrations/operators/op_123/bookingsUse this when GrabJet sends a booking request and the operator accepts, rejects, or cancels it.
Event: booking.accepted
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/bookings" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_booking_response_2001" \
-H "X-GrabJet-Event: booking.accepted" \
-d @booking.accepted.jsonEmpty-leg sync
POST /api/v1/integrations/operators/op_123/empty-legsUse this for empty-leg opportunity publish, hide, booked, or parent-booking linkage updates.
Event: empty_leg.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/empty-legs" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_empty_leg_1006" \
-H "X-GrabJet-Event: empty_leg.updated" \
-d @empty_leg.updated.jsonFlight status sync
POST /api/v1/integrations/operators/op_123/flight-statusUse this for scheduled, taxi, airborne, landed, delayed, cancelled, and telemetry-like status updates.
Event: flight.status_changed
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/flight-status" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_flight_status_1007" \
-H "X-GrabJet-Event: flight.status_changed" \
-d @flight.status_changed.jsonDispatch / compliance sync
POST /api/v1/integrations/operators/op_123/dispatch-complianceUse this for dispatch ready/blocked, permit status, and aircraft/crew/airport readiness signals.
Event: dispatch.readiness.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/dispatch-compliance" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_dispatch_1008" \
-H "X-GrabJet-Event: dispatch.readiness.updated" \
-d @dispatch.readiness.updated.jsonCompliance status sync
POST /api/v1/integrations/operators/op_123/dispatch-complianceUse this for permit, readiness, and compliance pass/fail state that should stay auditable before core use.
Event: dispatch.compliance.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/dispatch-compliance" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_compliance_1011" \
-H "X-GrabJet-Event: dispatch.compliance.updated" \
-d @dispatch.compliance.updated.jsonFinance / payout visibility
POST /api/v1/integrations/operators/op_123/finance-payoutsUse this for payout or settlement visibility. GrabJet remains payment source of truth.
Event: payout.status_changed
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/finance-payouts" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_payout_1009" \
-H "X-GrabJet-Event: payout.status_changed" \
-d @payout.status_changed.jsonNotification delivery sync
POST /api/v1/integrations/operators/op_123/notificationsUse this when your system reports delivery state for booking, dispatch, payout, or flight-status events.
Event: notification.delivery.updated
curl -X POST "https://api.grabjet.com//api/v1/integrations/operators/op_123/notifications" \
-H "Content-Type: application/json" \
-H "X-API-Key: $GRABJET_API_KEY" \
-H "Idempotency-Key: evt_notification_1010" \
-H "X-GrabJet-Event: notification.delivery.updated" \
-d @notification.delivery.updated.jsonOutbound Webhooks
Outbound events are sent by GrabJet to the operator system when GrabJet needs acceptance, cancellation sync, dispatch visibility, or finance visibility.
| Event | Meaning |
|---|---|
| booking.requested | GrabJet requests operator acceptance for a customer booking. |
| booking.cancelled | A GrabJet booking was cancelled or voided. |
| dispatch.ready | A mission cleared core dispatch readiness checks. |
| dispatch.blocked | A mission is blocked by aircraft, crew, maintenance, airport, or compliance truth. |
| payout.status_changed | A payout state changed and is visible to the operator. |
| flight.status_changed | Flight status changed and can be reflected to operator systems. |
| Payload Field | Meaning |
|---|---|
| event_id | Unique GrabJet event ID. Use it for duplicate-safe processing. |
| event_type | Business event such as booking.requested, dispatch.ready, empty_leg.booked, payout.status_changed. |
| operator_id | GrabJet operator identifier for the receiving operator. |
| created_at | UTC event creation timestamp. |
| reference_id | Optional business reference supplied by GrabJet, booking, dispatch, payout, or admin action. |
| data | Module-specific payload. Store unknown fields safely; GrabJet may add optional fields over time. |
Outbound Delivery & Retry Visibility
GrabJet outbound delivery is queue-based. That means core booking and dispatch work can continue even if an operator endpoint is temporarily unavailable. Operators should build receivers that are fast, duplicate-safe, and easy to retry.
| Feature | What Developers Should Know |
|---|---|
| Queue first | GrabJet queues outbound events before delivery so booking/dispatch workflows do not depend on an operator endpoint being online. |
| Signed delivery | Outbound webhooks include event identity and can be verified by the operator receiver. |
| Retry tracking | Temporary failures are retried and visible in the delivery queue with attempt count and last error. |
| Idempotency | Operators should treat event_id as duplicate-safe and avoid double-processing repeated deliveries. |
| Latency visibility | Delivery latency can be measured so operators can see whether webhook delivery is healthy. |
| Manual resend | GrabJet admin can retry failed deliveries after the operator receiver is fixed. |
Webhook Receiver Requirements
If GrabJet sends events to your system, your receiver must be reliable, quick to acknowledge, and safe against duplicates.
| Requirement | Rule |
|---|---|
| Public HTTPS URL | Operator webhook receiver must be reachable over HTTPS in production. |
| Response status | Return any 2xx status only after the event is safely accepted or queued. |
| Timeout | Respond quickly. Long processing should happen asynchronously after accepting the event. |
| Signature verification | Verify X-GrabJet-Signature against the raw request body before processing. |
| Duplicate events | Use event_id or Idempotency-Key to ignore safe duplicates. |
| Error response | Return 4xx for permanent validation/auth failures and 5xx only for temporary failures. |
End-to-End Flow Diagrams
These are the practical integration flows most operators implement first. Treat each row as a real-world sandbox workflow before going live.
| Flow | Direction | What Happens |
|---|---|---|
| Aircraft sync | Operator system → GrabJet | Operator sends aircraft.updated with tail, type, range, current airport, readiness, maintenance release. |
| Availability sync | Operator system → GrabJet | Operator sends availability.updated. GrabJet stages it and flags conflicts with active bookings. |
| Booking request | GrabJet → Operator | GrabJet sends booking.requested to the operator webhook when operator acceptance is required. |
| Booking response | Operator system → GrabJet | Operator sends booking.accepted or booking.rejected to the bookings endpoint. |
| Flight status | Operator system → GrabJet | Operator sends scheduled, taxi, airborne, landed, delayed, or cancelled updates. |
| Payout visibility | GrabJet → Operator | GrabJet remains payment source of truth and can send payout.status_changed for visibility. |
Aircraft Sync
Booking Round Trip
Flight Status
Local Operator Data Contract
Local operators should send GrabJet's generic contract. Canonical IDs are welcome, but stable local references such as booking_reference, empty_leg_reference, payout_reference, notification_reference, crew_reference, and flight_reference are also accepted.
| Module | Accepted Identity | Required Business Fields | Useful Optional Fields | Direction |
|---|---|---|---|---|
| Aircraft | tail_number or registration | aircraft_type/type/model | status, seats, range, base/current airport, readiness_status, document/insurance/certificate status, maintenance release, MEL/CDL | Operator → GrabJet |
| Crew | crew_id, crew_reference, email, or license_number | none beyond identity | name, role, license expiry, medical expiry, type rating, duty_status, available window, assigned aircraft | Operator → GrabJet |
| Availability | tail_number, registration, aircraft_id, or aircraft_external_id | available_from/start_time and available_to/end_time | airport, status, booked hold, booking_reference, conflict status/reason, manual review flag, notes | Operator → GrabJet |
| Pricing | external_id, pricing_reference, aircraft reference, route, or booking_reference | price/hourly_rate/quote_total | currency, route/empty-leg price, discount, fees, reposition policy/fee, minimum hours, tax/surcharge, valid_until | Operator → GrabJet |
| Maintenance | tail_number, registration, aircraft_id, or aircraft_external_id | status or maintenance_status | grounded, MEL/CDL items, release status/reference, release expiry, notes | Operator → GrabJet |
| Documents | document_id, document_reference, license_number, or certificate_number | document_type/type | document number, tail/aircraft ref, crew ref/license, issue/expiry date, file URL, issuer, status | Operator → GrabJet |
| Booking | booking_id, booking_reference, or external_id | none beyond identity | accepted, status, operator confirmation, cancel/reject reason, dispatch_state, ETA, notes | Two-way |
| Empty Legs | empty_leg_id, empty_leg_reference, or parent booking reference | departure/arrival airport, origin/destination, or route | publish/booking state, linked parent booking, price, currency, availability/departure window, passengers | Two-way |
| Flight Status | flight_id, flight_reference, booking reference, or tail_number | status or phase | scheduled/actual times, position, altitude, speed, heading, ETA, delay reason | Operator → GrabJet |
| Dispatch | dispatch/aircraft/booking reference or tail_number | none beyond identity | dispatch_status, aircraft/crew/airport readiness, permit/compliance/readiness status, blocked_by, resolution_required | Two-way |
| Compliance | compliance, booking, flight, aircraft, or tail reference | compliance/dispatch/readiness/permit status | permit_reference, blocked_by, resolution_required, notes | Two-way |
| Finance / Payout | payout, payment, booking, or external reference | status/payout_status/payment_status | amount, currency, settlement reference, estimated settlement date, scheduled/paid time, failure reason | GrabJet → Operator mostly |
| Notifications | event, notification, booking, or related booking reference | event_type/type/message/description | channel, delivery_status, attempts, last_error | Two-way visibility |
| Enum / Status | Allowed Values |
|---|---|
| Aircraft status | active, inactive, maintenance, unavailable |
| Availability status | available, unavailable, scheduled, maintenance, blocked |
| Booking status | requested, accepted, rejected, cancelled, updated |
| Empty-leg status | draft, published, booked, hidden, cancelled |
| Flight status | scheduled, taxi, airborne, landed, delayed, cancelled |
| Dispatch status | ready, blocked, pending |
| Payout status | pending, scheduled, processing, paid, failed, cancelled |
| Notification delivery | queued, delivered, failed, retrying, skipped |
Full Payload Field Reference
Every endpoint uses a shared event envelope plus module-specific fields inside data. During onboarding, GrabJet can map small additional operator fields into this structure.
| Field | Type | Requirement | Validation / Meaning |
|---|---|---|---|
| event_id | string | Required | Unique event reference. Used for idempotency and audit trace. |
| event_type | string | Required | Event name, for example aircraft.updated or booking.accepted. |
| operator_reference | string | Required | Your stable operator/system reference. |
| occurred_at | ISO 8601 string | Required | UTC event time from the source system. |
| data.tail_number | string | Required for aircraft/flight | Aircraft registration or tail number. |
| data.status | string | Required for state updates | Module-specific status such as available, airborne, accepted, blocked. |
| data.booking_id / data.booking_reference | string | Required for booking/flight/dispatch/payout when available | GrabJet booking ID or booking reference. |
| data.empty_leg_id / data.empty_leg_reference | string | Required for empty-leg sync | Operator or GrabJet empty-leg reference. |
| data.payout_id / data.payout_reference | string | Required for payout sync | Payout or settlement reference. |
| data.notification_id / data.notification_reference | string | Required for notification sync | Delivery or notification reference. |
| data.currency | string | Required for money | ISO currency code, for example USD. |
| data.amount / price | number | Required for money | Decimal amount unless a different minor-unit rule is agreed during onboarding. |
| data.notes / message | string | Optional | Human-readable note for operations or manual review. |
Payload Examples
Use these examples to understand the expected event envelope. The exact field mapping can be adjusted during onboarding, but every event should include a stable event reference and operator reference.
{
"event_id": "evt_aircraft_1001",
"event_type": "aircraft.updated",
"operator_reference": "OP-ACME-001",
"occurred_at": "2026-06-29T10:30:00Z",
"data": {
"tail_number": "N900GJ",
"aircraft_type": "Gulfstream G650",
"seats": 14,
"max_range_nm": 7000,
"current_airport": "OMDB",
"status": "available",
"maintenance_release_status": "released",
"mel_cdl_restricted": false
}
}Idempotency Guide
Idempotency prevents duplicate bookings, duplicated aircraft updates, and repeated webhook side effects when networks timeout or operators retry requests.
| Rule | Explanation |
|---|---|
| Key format | Use a stable key per event, for example evt_aircraft_1001 or provider-event-id. |
| Retry behavior | If a network timeout occurs, retry with the exact same Idempotency-Key and same payload. |
| Duplicate response | Duplicate keys should not create duplicate core changes. GrabJet may return existing accepted/staged result. |
| Key scope | Use unique keys per operator and event. Do not reuse the same key for different payloads. |
| Retention | GrabJet keeps dedupe evidence for audit/replay protection according to the integration policy. |
Webhook Retry Rules
Operators should retry safely based on response status. When retrying a write request after a timeout or 5xx, use the same idempotency key.
| Response | What To Do |
|---|---|
| 2xx | Consider delivered. Do not retry. |
| 400 / 422 | Payload or mapping issue. Fix data before retrying with a new event if payload changes. |
| 401 / 403 | Credential or permission issue. Do not retry blindly; rotate/check credentials. |
| 409 | Conflict or duplicate. Review response and conflict queue before retrying. |
| 429 | Rate limited. Retry after backoff or Retry-After header if provided. |
| 5xx / timeout | Retry with exponential backoff and the same idempotency key. |
Errors
Failed requests return a stable error envelope. Validation errors do not apply data into core systems; they are recorded for review.
Error response
{
"success": false,
"error": {
"code": "invalid_payload",
"message": "tail_number is required",
"field": "data.tail_number",
"request_id": "req_01J..."
}
}Error Troubleshooting
Use this table when a sandbox request fails. Most failures are caused by wrong environment credentials, missing module permissions, duplicate idempotency keys, or payload mapping differences.
| Error / Symptom | Likely Cause | Fix |
|---|---|---|
| 401 invalid api key | Missing, expired, or environment-mismatched key. | Check GRABJET_API_KEY and make sure sandbox key is used with sandbox URL. |
| 403 module not enabled | Credential is valid but module is not enabled. | Ask GrabJet admin to enable the module for this operator profile. |
| 409 duplicate event | Same Idempotency-Key already processed. | Treat as safe duplicate unless payload differs; do not create a second event. |
| 409 availability conflict | Availability conflicts with active booking hold. | Review manual conflict with operations before applying. |
| 422 mapping failed | Payload field cannot map to GrabJet model. | Check field names, required values, airport codes, and enum values. |
| 429 rate limited | Too many requests in a short window. | Back off and retry later with same idempotency key. |
| Webhook not received | Operator endpoint unreachable or signature rejected. | Check public HTTPS URL, HMAC secret, firewall, and response status. |
Status Codes
Use status codes to decide whether to retry, fix the payload, or contact GrabJet support. Always retry write requests with the same idempotency key.
| Status | Meaning |
|---|---|
| 200 | Request accepted and processed successfully. |
| 202 | Request accepted for staging/review but not yet applied to core systems. |
| 400 | Invalid payload, missing field, or failed validation. |
| 401 | Missing or invalid API key/token/signature. |
| 403 | Credential is valid but not allowed for this operator/module. |
| 409 | Duplicate idempotency key or availability/booking conflict requiring review. |
| 422 | Payload is syntactically valid but cannot be mapped to GrabJet fields. |
| 429 | Rate limit exceeded. |
| 500 | Unexpected server error. Retry only with the same idempotency key. |
Sample Success Responses
Successful responses confirm whether GrabJet accepted the event immediately or staged it for manual review. A 2xx response does not always mean the data was directly applied to production core records.
Accepted / validated response
{
"success": true,
"data": {
"event_id": "evt_aircraft_1001",
"operator_id": "op_123",
"module": "aircraft",
"status": "accepted",
"stage": "validated",
"duplicate": false,
"request_id": "req_01J...",
"received_at": "2026-06-29T10:30:02Z"
}
}Staged for manual review response
{
"success": true,
"data": {
"event_id": "evt_availability_1002",
"status": "staged_for_review",
"attention_required": true,
"reason": "availability conflicts with active GrabJet booking hold",
"conflict_reference": "conflict_789"
}
}Validation Enum Reference
Use these values where applicable. If your system has different values, map them during onboarding instead of sending unknown statuses directly.
| Field / Area | Allowed Values |
|---|---|
| aircraft status | available, unavailable, maintenance, grounded, inactive |
| maintenance_release_status | released, pending, expired, blocked |
| booking decision | booking.accepted, booking.rejected, booking.cancelled |
| empty leg status | draft, published, hidden, booked, cancelled, expired |
| flight status | scheduled, taxi, airborne, landed, delayed, cancelled |
| dispatch status | ready, blocked, attention_required, pending_review |
| permit status | not_required, pending, approved, rejected, expired |
| payout status | pending, scheduled, processing, paid, failed, cancelled |
| notification delivery | queued, delivered, failed, retrying, skipped |
Webhook Verification
For API/webhook operators, GrabJet expects signed payloads. Sign the raw JSON request body with the webhook secret issued during onboarding.
HMAC signature pattern
signature = HMAC_SHA256(
secret = webhook_secret,
message = raw_request_body
)
Header:
X-GrabJet-Signature: sha256=<hex_digest>Verify signature in your stack
Always verify against the raw request body before JSON parsing changes whitespace or ordering.
import crypto from "node:crypto"
export function verifyGrabJetSignature(rawBody, signatureHeader, webhookSecret) {
const expected = "sha256=" + crypto
.createHmac("sha256", webhookSecret)
.update(rawBody, "utf8")
.digest("hex")
const expectedBuffer = Buffer.from(expected)
const receivedBuffer = Buffer.from(signatureHeader || "")
return expectedBuffer.length === receivedBuffer.length &&
crypto.timingSafeEqual(expectedBuffer, receivedBuffer)
}Postman Collection / OpenAPI
GrabJet can provide a sandbox Postman collection or OpenAPI file after operator approval. Until credentials are issued, use the files below to prepare payloads and environment variables.
| Artifact | Purpose | Availability |
|---|---|---|
| Postman collection | Import endpoints, headers, sample payloads, and sandbox variables. | Downloadable starter file below |
| OpenAPI file | Generate typed clients or validate request/response schema. | Downloadable starter file below |
| Mock payload pack | Run local tests before real credentials are available. | Available during technical onboarding |
Postman environment variables
GRABJET_BASE_URL = https://api.grabjet.com/
GRABJET_OPERATOR_ID = op_123
GRABJET_API_KEY = gj_sandbox_...
GRABJET_WEBHOOK_SECRET = whsec_...Downloadable Integration Pack
These starter files make the docs easier to test locally. Replace sample values with sandbox credentials after GrabJet approves your operator access.
Postman collection
Import endpoints, headers, and sample module requests.
Download
OpenAPI contract
Generate clients or validate request/response schemas.
Download
Live access checklist
Use during final sandbox-to-production sign-off.
Download
SDK / Client Helper Examples
GrabJet does not require a heavy SDK. Many operators can use a tiny server-side helper around fetch or requests. Keep credentials on the server.
class GrabJetClient {
constructor({ baseUrl, apiKey, operatorId }) {
this.baseUrl = baseUrl.replace(/\/$/, "")
this.apiKey = apiKey
this.operatorId = operatorId
}
async postModule(modulePath, eventName, idempotencyKey, payload) {
const response = await fetch(
`${this.baseUrl}/api/v1/integrations/operators/${this.operatorId}/${modulePath}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": this.apiKey,
"Idempotency-Key": idempotencyKey,
"X-GrabJet-Event": eventName,
},
body: JSON.stringify(payload),
}
)
if (!response.ok) throw new Error(await response.text())
return response.json()
}
}Testing
Before asking for live access, run these tests in sandbox. This protects the operator and GrabJet from duplicate events, bad payloads, booking conflicts, and broken webhook retry behavior.
| Test | Expected Result |
|---|---|
| Happy path | Send one valid aircraft update and verify it enters staged/ready state. |
| Duplicate event | Replay the same Idempotency-Key and verify no duplicate core change is created. |
| Bad auth | Send request without valid key/signature and confirm 401. |
| Malformed payload | Remove a required field and confirm stable validation error. |
| Conflict | Send availability that conflicts with an active booking and confirm manual review. |
| Booking round-trip | Receive booking.requested and return booking.accepted or booking.rejected. |
| Webhook retry | Temporarily fail your receiver and confirm retry behavior with same event reference. |
Sandbox Test Checklist
Use this checklist before asking GrabJet for production access. It gives both teams a simple pass/fail view of whether sandbox worked.
| Step | Checklist Item | Evidence Needed |
|---|---|---|
| 1 | Request sandbox access | Submit company, contact, modules, auth preference, and technical contact. |
| 2 | Receive credentials | Configure base URL, API key, webhook secret, and operator ID in server env. |
| 3 | Send aircraft update | POST aircraft.updated and confirm accepted/staged response. |
| 4 | Send availability update | POST availability.updated and verify conflict handling if availability overlaps bookings. |
| 5 | Run booking round-trip | Receive booking.requested, then POST booking.accepted or booking.rejected. |
| 6 | Send flight status | POST flight.status_changed through scheduled → airborne → landed sample flow. |
| 7 | Test duplicates | Replay same idempotency key and confirm no duplicate processing. |
| 8 | Test bad auth | Send invalid key/signature and confirm request is rejected. |
| 9 | Review results | Attach logs/screenshots/results to your admin review notes. |
| 10 | Production approval | GrabJet issues production credentials after sign-off. |
Security Requirements
Production access requires basic integration security controls. GrabJet may request screenshots, logs, or implementation notes for these items during go-live review.
| Requirement | Rule |
|---|---|
| HTTPS only | All API and webhook URLs must use HTTPS in production. |
| Secret storage | Store API keys and webhook secrets server-side only. Never expose in browser/mobile clients. |
| HMAC signatures | Use raw request body and shared secret to verify webhook authenticity. |
| IP allowlist | Optional if your team uses static server IPs and wants extra inbound protection. |
| Secret rotation | Rotate sandbox/production secrets when staff changes, systems migrate, or credentials are suspected leaked. |
| Log redaction | Do not log full API keys, bearer tokens, webhook secrets, passport/license numbers, or medical document details. |
| Least privilege | Enable only the modules your operator integration actually needs. |
Operational Safety Controls
GrabJet can pause integration traffic without shutting down the operator's core portal workflow. These controls are designed for safety incidents, bad data, endpoint failures, credential exposure, or supervised go-live decisions.
| Control | Effect | When Used |
|---|---|---|
| Pause inbound | Blocks external API and webhook intake before data reaches staging. | Unsafe payloads, suspected credential leak, or bad automated sync. |
| Pause outbound | Stops new GrabJet-to-operator outbound events from being queued. | Operator receiver is down, returning bad responses, or receiving duplicate side effects. |
| Rotate credentials | Reissues sandbox or production credentials with audit trail. | Secret exposure, team change, system migration, or compromised endpoint. |
| Force live override | Super Admin-only emergency/demo override with mandatory reason and audit trail. | Exceptional supervised cases only; real sandbox review is still expected. |
| Resume integration | Reopens traffic after review, receiver fix, or credential rotation. | After the safety condition is resolved and verified. |
Module Mapping
| Module | Direction | Typical Fields |
|---|---|---|
| Aircraft | Operator to GrabJet | tail number, type, seats, range, airport, readiness, documents |
| Crew | Operator to GrabJet | pilot identity, license, medical, duty availability |
| Availability | Two-way | availability windows, booked holds, conflicts, manual review |
| Pricing | Operator to GrabJet | hourly rates, route pricing, reposition policy, fees |
| Maintenance | Operator to GrabJet | grounded state, release status, MEL/CDL restrictions |
| Booking | GrabJet to Operator | booking request, accept/reject, cancel, dispatch state |
| Empty Legs | Two-way | opportunity, publish/hide state, booking state, linked parent booking |
| Flight Status | Operator to GrabJet | scheduled, taxi, airborne, landed, delayed, cancelled |
| Dispatch / Compliance | Two-way visibility | dispatch ready/blocked, permit/compliance, readiness signals |
| Finance / Payout | GrabJet source of truth | payment and payout visibility |
| Notifications / Webhooks | Two-way visibility | booking, dispatch, payout, and flight status event notifications |
Live Access Checklist
Portal-only operators can go live after business verification, fleet readiness, payout setup, and portal training. API-connected operators need the additional technical checks below.
| Gate | Required Before Production |
|---|---|
| Business approval | Company, AOC/certificate, aircraft, documents, regions, and contacts verified. |
| Portal readiness | Operator admin users invited, trained, and able to manage fleet/bookings/payout visibility. |
| Fleet readiness | Aircraft status, range, documents, maintenance release, and operating airports reviewed. |
| Payout setup | Payout account, settlement contact, and finance workflow confirmed. |
| Optional API credentials | Sandbox base URL, API key, and webhook secret configured if automation is enabled. |
| Optional initial sync | Aircraft, availability, and required module sync passed validation if API/webhook automation is used. |
| Optional booking round-trip | GrabJet booking request accepted/rejected by operator sandbox if API booking sync is enabled. |
| Security sign-off | Auth, HMAC, IP/rate-limit policy, and secret storage approved for API-connected operators. |
Glossary
Shared language for operators, developers, and operations teams during integration work.
| Term | Meaning |
|---|---|
| AOC | Air Operator Certificate. Regulatory approval for commercial air operations. |
| MEL/CDL | Minimum Equipment List / Configuration Deviation List. Determines whether aircraft can dispatch with restrictions. |
| FBO | Fixed Base Operator. Ground handling, fuel, and passenger support at an airport. |
| PPR | Prior Permission Required. Airport or slot approval needed before operating. |
| Empty leg | A repositioning flight segment that can be sold after or before a primary booking. |
| Dispatch | Operational release decision across aircraft, crew, airport, maintenance, and compliance readiness. |
| HMAC | Hash-based message authentication code used to verify webhook payload authenticity. |
| Idempotency | Duplicate-safe request behavior using a stable key per event. |
| ICAO / IATA | ICAO is usually 4-letter airport code; IATA is usually 3-letter commercial airport code. |
| Sandbox | Non-production environment for integration tests before live credentials are issued. |
Changelog
Track public integration doc and API contract changes here. Operators should review changelog entries before production credential upgrades.
| Version | Change |
|---|---|
| Draft v1 | Initial public operator integration docs for portal, API, webhook, and sandbox-first onboarding. |
| Draft v1.1 | Added full module examples, field reference, idempotency, retry rules, security, and sandbox checklist. |
| Future | Expanded OpenAPI/Postman package and more starter helpers can be added later if operators need them. |
Developer FAQ
Common questions from operators and engineering teams during onboarding.
| Question | Answer |
|---|---|
| Can I start portal-only? | Yes. Most small operators should start with the operator portal, then add API automation later. |
| When do I get production keys? | After business verification, sandbox tests, booking round-trip, security checks, and go-live sign-off. |
| What if I send the same event twice? | Use the same Idempotency-Key. GrabJet treats it as a duplicate instead of creating duplicate side effects. |
| Can GrabJet consume my existing system data? | Yes. After onboarding, start with generic API or webhook payloads from your existing tool. |
| Do I need OAuth? | No for the normal small-operator flow. API key plus signed webhook is the standard path. |
| What if my payload fields are different? | GrabJet can map small field differences during onboarding. Start with the generic API/webhook contract first. |
Support
During onboarding, GrabJet separates business, operations, technical, and finance support so each issue reaches the right team quickly.
| Support Area | Covers |
|---|---|
| Business onboarding | Company verification, AOC/certificate, operating region, commercial terms. |
| Operations support | Booking acceptance, dispatch readiness, delay/cancellation coordination. |
| Technical support | Sandbox credentials, webhook signatures, API payloads, mapping errors. |
| Finance support | Payout account setup, settlement status, invoice/payment questions. |
| Priority | When To Use | Target First Response | Escalation Path |
|---|---|---|---|
| P0 Production outage | Production integration down, booking/dispatch blocked for live operator. | 15 minutes | Integration support + operations escalation |
| P1 Critical workflow issue | Booking accept/reject, dispatch, or payout visibility failing for one live operator. | 30 minutes | Technical support + operator success |
| P2 Sandbox blocker | Sandbox credential, payload, mapping, or webhook test blocked. | 1 business day | Technical onboarding |
| P3 Docs / mapping question | Field mapping clarification or non-blocking docs issue. | 2 business days | Developer support |