Skip to main content

Documentation Index

Fetch the complete documentation index at: https://dev.1st.app/llms.txt

Use this file to discover all available pages before exploring further.

The AMS-integration job: your AMS (Hudl, Catapult, Kitman, custom) already has player IDs. You want to link a 1st sensor to a specific player so the readings from that sensor are tagged correctly in your analytics. 1st doesn’t model players directly. Instead, every sensor has a free-form metadata field you populate from your side. Store your AMS’s player ID (or room ID, or whatever identifier matters to you) in there, then filter sensors by metadata when pulling data.

Three steps

1

Tag a sensor with your AMS player ID

You’ll need a Read and write key for this. Mint one under Integrations → API access if you don’t already have one — read-only keys can’t PATCH.
curl -X PATCH https://api.1st.app/v1/sensors/SENSOR_ID \
  -H "Authorization: Bearer $ST_API_KEY_RW" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "metadata": {
      "hudl_player_id": "12345",
      "position": "GK"
    }
  }'
Limits: 20 keys per metadata object, 500 chars per value, key max 64 chars. Stringify integer IDs client-side — metadata values are always strings.
PATCH with metadata is replace-not-merge. Sending {"metadata":{"a":"1"}} replaces the entire object, so keys you don’t mention are removed. To preserve existing keys, read the sensor first (GET /v1/sensors/{id}), merge client-side, then send the full merged object back.
2

Look up by your AMS ID

Once tagged, filter /v1/sensors by any metadata key:
curl "https://api.1st.app/v1/sensors?metadata.hudl_player_id=12345" \
  -H "Authorization: Bearer $ST_API_KEY"
Returns only sensors whose metadata contains the exact match. Repeat the parameter to AND multiple conditions:
curl "https://api.1st.app/v1/sensors?metadata.hudl_player_id=12345&metadata.position=GK" \
  -H "Authorization: Bearer $ST_API_KEY"
The query uses the metadata GIN index, so it stays fast as your fleet grows.
3

Pull readings tied to the player

Once you have the sensor_id from step 2, the standard readings endpoint takes you the rest of the way:
curl "https://api.1st.app/v1/sensors/SENSOR_ID/readings?from=2026-05-13T00:00:00Z&to=2026-05-14T00:00:00Z" \
  -H "Authorization: Bearer $ST_API_KEY"
Or in bulk via CSV for offline analysis:
curl "https://api.1st.app/v1/readings.csv?from=2026-05-01T00:00:00Z&to=2026-05-31T00:00:00Z&sensors=SENSOR_ID&shape=wide" \
  -H "Authorization: Bearer $ST_API_KEY" > player-12345-may.csv

Patterns that work well

  • One metadata key per AMS: if you sync to multiple systems, use distinct keys (hudl_player_id, catapult_athlete_id, kitman_athlete_id) so each integration can filter without collision.
  • Tag rooms, not athletes: sensors live in rooms, not on people. When an athlete changes rooms, retag the new sensor — don’t try to follow the person.
  • Use a single read_write key per AMS: name keys after the system they’re for (“Hudl sync”) so the audit log is readable.

Concurrency caveat

Two clients PATCHing different metadata keys on the same sensor at the same time will clobber each other — last write wins, no merge. For V1 this matches Stripe’s PATCH-as-replace contract. If your team runs multiple AMS integrations against the same sensor, gate writes behind a single owner per sensor or use the same Idempotency-Key on retries.