Sorry, TGIF Network requires JavaScript to be enabled.

TGIF API Helper

Developer integration reference for supported TGIF machine-to-machine APIs. This page documents the public client contract, authentication model, request formats and safe client behaviour.

Current documented API: Static Talkgroups API v1. The Static TG API token is separate from the normal TGIF Hotspot Security password used by the hotspot's DMR connection.

Static Talkgroups API — quick start

  1. Connect the hotspot to TGIF using its normal TGIF Hotspot Security Key.
  2. Create a device-scoped token from Static TG API Tokens.
  3. Create the token for the exact DMR ID / ESSID used by the hotspot on TGIF.
  4. Send HTTPS requests to https://api.tgif.network/v1/static-talkgroups/{device}.
  5. Read once at startup or on manual refresh; write only when configuration changes.
curl -sS \ -H "Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>" \ https://api.tgif.network/v1/static-talkgroups/123456701

Replace 123456701 with the exact hotspot/repeater DMR ID presented to TGIF. Never publish or log the bearer token.

Authentication and device scope

Bearer token

Every request uses an HTTP Authorization header:

Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>

The full secret is shown only once when the token is created. TGIF stores only a cryptographic hash of the secret.

Runtime authorization

A valid token is not enough by itself. TGIF also verifies that the requested device matches the token, is currently connected, belongs to the token account and is using TGIF secure hotspot authentication.

A token created for one ESSID cannot control another ESSID. A token for 123456701 cannot be used against 123456702.

Endpoint and data model

https://api.tgif.network/v1/static-talkgroups/{device_dmr_id}

{device_dmr_id} must contain 6 to 9 decimal digits. Static memberships are represented as a timeslot and talkgroup pair.

{"slot":2,"talkgroup":31665}

Talkgroup values must be between 1 and 16,777,215 and must not be a TGIF reserved/special destination. TG 9, 777, 4000, 9990 and 31000 are protected.

HTTP methods

MethodPurposeRequest body
GETRead current Static TG state and supported timeslots.None
POSTAdd one membership. Duplicate adds are idempotent.{"slot":2,"talkgroup":31665}
DELETERemove one membership. Removing an absent membership is idempotent.{"slot":2,"talkgroup":31665}
PUTReplace the complete membership set atomically.{"memberships":[...]}
OPTIONSReturn the allowed methods.None

Read state

curl -sS \ -H "Accept: application/json" \ -H "Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>" \ https://api.tgif.network/v1/static-talkgroups/123456701

Add TG 31665 on TS2

curl -sS -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>" \ --data '{"slot":2,"talkgroup":31665}' \ https://api.tgif.network/v1/static-talkgroups/123456701

Delete TG 31665 on TS2

curl -sS -X DELETE \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>" \ --data '{"slot":2,"talkgroup":31665}' \ https://api.tgif.network/v1/static-talkgroups/123456701

Replace the complete set

curl -sS -X PUT \ -H "Accept: application/json" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer <YOUR_STATIC_TG_API_TOKEN>" \ --data '{"memberships":[{"slot":2,"talkgroup":31665}]}' \ https://api.tgif.network/v1/static-talkgroups/123456701

Write bodies must use Content-Type: application/json and are limited to 4096 bytes.

Response examples

GET success

{ "ok": true, "device": 123456701, "enabled": true, "limit": 5, "supports_ts1": false, "supports_ts2": true, "memberships": [ {"slot": 2, "talkgroup": 31665} ], "request_id": "..." }

Mutation success

{ "ok": true, "device": 123456701, "changed": true, "runtime_seen": true, "memberships": [ {"slot": 2, "talkgroup": 31665} ], "request_id": "..." }

changed:false means the requested state already existed, so no membership write or CallMGR reload was required. runtime_seen:true means a live CallMGR subscriber saw the reload notification.

HTTP status and error handling

HTTPMeaningClient action
400Invalid device, JSON or request structure.Fix the request; do not retry unchanged input.
401Missing, malformed, revoked or invalid API credential.Check or recreate the credential.
403Account/device ownership, secure-hotspot or policy authorization failed.Check device scope and TGIF secure connection.
409Device offline, Static TG disabled or concurrent update conflict.Refresh state later; do not spin.
413Request body too large.Reduce the request.
415Write request is not application/json.Send the correct Content-Type.
422Unsupported slot, reserved/invalid TG, duplicate entry or membership limit.Correct the requested configuration.
426HTTPS is required.Use the HTTPS API URL.
429Rate limited at the HTTP edge.Stop and retry later with backoff/jitter.
503Backing-store/runtime state could not be safely read or written.Back off and retry later.

JSON errors contain ok:false, an error code and a request_id for support correlation.

Required client behaviour

Continuous polling is not supported. The API is an event-driven configuration interface, not a live telemetry feed.

  1. Perform one GET when the client starts or its configuration UI opens.
  2. Cache the returned state locally.
  3. Send POST, DELETE or PUT only when the user changes configuration.
  4. Allow an explicit manual refresh to perform another GET.
  5. On network failure, 429 or 503, use delayed exponential backoff with random jitter if an automatic retry is necessary.

Do not use a synchronized fixed retry timer, daemon loop or short polling interval.

Hotspot integration

Pi-Star / WPSD

Linux-based hotspots can use the TGIF one-shot helper and store client settings in /etc/tgif-static-api.conf.

The configuration contains the production API URL, the device-scoped API credential and the exact DMR ID / ESSID used by the hotspot.

Protect that file with restrictive permissions. The reference helper supports list, add and del operations and deliberately does not run a polling loop.

openSPOT

openSPOT can use TGIF Static Talkgroups while securely connected, but it is an appliance and does not use the Pi-Star filesystem/helper setup.

Create the API credential for the exact openSPOT DMR ID / ESSID shown to TGIF. Manage Static TG state through TGIF Self-Care or an external application.

Do not put the Static TG API credential into the normal openSPOT TGIF/DMR network password field.

TGIF implementation behaviour

These behaviours are part of the production-safety contract and are useful when designing integrations:

Reserved destinations

TG 9, 777, 4000, 9990 and 31000 are protected from Static TG configuration. Validation is enforced server-side.

Security guidance for application developers
  • Treat the API credential as a password and never include it in URLs.
  • Do not write credentials to application logs, crash reports or analytics.
  • Use protected credential storage when the platform provides it.
  • Provide a clear credential-revocation path to users.
  • Never commit live credentials into source control or example configuration.