Sorry, TGIF Network requires JavaScript to be enabled.

TGIF Static Talkgroups API β€” Developer Integration

Integration reference for hotspot and dashboard developers adding TGIF Static Talkgroup management to their client.

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. Pi-Star: go to Admin β†’ Expert β†’ API Keys, paste the token into TGIF Static Talkgroups API Key β†’ apikey, and select Apply Changes. Return to the Admin dashboard to use the TGIF Static TG Manager.
  5. Other clients / developers: store the token in the client’s dedicated TGIF Static Talkgroups API token setting.
  6. Send HTTPS requests to https://api.tgif.network/v1/static-talkgroups/{device}.
  7. 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": "..." }

The limit value is the maximum number of Static TG memberships allowed per supported timeslot for that hotspot. With a limit of 5, a two-slot hotspot may therefore hold up to 5 on TS1 and 5 on TS2.

Pi-Star / MMDVM timeslots: a simplex or single-timeslot hotspot uses TS2 only for Static Talkgroups. A true duplex/repeater-style MMDVM device may expose TS1 and TS2 when the live TGIF session reports both slots as supported. Clients must follow supports_ts1 and supports_ts2; do not infer Static TG capability from the legacy Pi-Star dynamic manager controls.

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.

Dashboard integration pattern

This section is for developers adding TGIF Static Talkgroup controls to another hotspot dashboard.

  1. Use the exact DMR ID / ESSID that the hotspot presents to TGIF.
  2. Provide a separate Static TG API Token setting in the dashboard.
  3. Keep the saved credential on the hotspot side and do not expose it in page output or logs.
  4. Perform one GET when the Static TG panel opens and follow supports_ts1, supports_ts2 and limit from the response.
  5. Use POST to add a membership, DELETE to remove one, and PUT only to replace the complete set.
  6. After a successful change, refresh the displayed state once. Do not run a polling loop.

Timeslots: simplex hotspots normally use TS2. Duplex devices may support TS1 and TS2. Always follow the capability fields returned by TGIF.

Network behaviour: use HTTPS with certificate and hostname verification. For 429, 503 or transient failures, back off rather than repeatedly retrying.

Pi-Star reference: install the credential at Admin β†’ Expert β†’ API Keys β†’ TGIF Static Talkgroups API Key β†’ apikey β†’ Apply Changes. Pi-Star then reads state for that hotspot and exposes the TGIF Static TG Manager on the Admin dashboard. Other clients should follow the same credential-handling model without exposing the token in page output or logs.