Public — no login required

LLMs and tools can fetch the raw skill (Markdown) without registering:

https://playerping.me/skills/playerping-api/SKILL.md

To call the API you still need an organizer API key from Settings. The skill file itself is public documentation.

PlayerPing Public API


You are operating against PlayerPing, a sports event organizer product.

Use only the public API under `/api/v1` with a Bearer API key. Do not use

session cookies, admin routes, or invent endpoints.


Public skill URL (no registration)


Anyone can fetch this skill without creating an account:


https://playerping.me/skills/playerping-api/SKILL.md


Human-readable mirror: https://playerping.me/docs/agent-skill


Calling the API still requires an organizer `pp_live_…` API key (Settings → API Keys).


Prerequisites


  • API key — User provides `PLAYERPING_API_KEY` (or pastes a `pp_live_…` key).
  • Prefer an environment variable / secret store over repeating the key in chat.
  • Never commit keys, log them, or put them in artifacts/PR bodies.
  • Base URL (default production):

https://playerping.me/api/v1

Override only if the user gives another host (preview/local).


Auth on every request


Authorization: Bearer

Content-Type: application/json


Missing/invalid key → `401`. Keys cannot perform admin actions.


Safety rules


  • Default `notify: false` when adding players to events. Only set `notify: true` when the user explicitly wants SMS/email/WhatsApp invitations sent (this can spend credits).
  • Confirm before deleting players/events or sending notifications (`notify: true`).
  • Do not create disposable junk data on a production account unless asked; clean up smoke-test resources you create.
  • Magic-link `token` fields are never returned; do not ask for them or invent RSVP URLs.
  • Treat phone numbers and emails as PII — summarize in replies when possible.

curl helper


export PLAYERPING_API_KEY='pp_live_…'

export PLAYERPING_API='https://playerping.me/api/v1'

alias pp='curl -sS -H "Authorization: Bearer $PLAYERPING_API_KEY" -H "Content-Type: application/json"'


Errors are JSON: `{ "error": "message" }` with status `400|401|402|403|404|500`.




Players


| Method | Path | Purpose |

|--------|------|---------|

| GET | `/players` | List roster (+ `averageStars`, `totalRatings`) |

| POST | `/players` | Create |

| GET | `/players/:id` | Get one |

| PATCH | `/players/:id` | Update |

| DELETE | `/players/:id` | Delete |


Create / update body


{

"name": "Alex Rivera",

"phone": "+15551234567",

"gender": "M",

"sport": "Tennis",

"email": "alex@example.com",

"clubId": null

}


| Field | Required | Notes |

|-------|----------|-------|

| `name` | yes | string |

| `phone` | yes | E.164, e.g. `+64211234567` |

| `gender` | yes | `M` \| `F` \| `OTHER` |

| `sport` | yes | e.g. `Tennis` |

| `email` | no | |

| `clubId` | no | must be accessible to the key owner |


Examples


pp "$PLAYERPING_API/players"

pp -X POST "$PLAYERPING_API/players" -d '{"name":"Alex","phone":"+15551234567","gender":"M","sport":"Tennis"}'

pp -X PATCH "$PLAYERPING_API/players/PLAYER_ID" -d '{"name":"Alex R","phone":"+15551234567","gender":"M","sport":"Tennis"}'

pp -X DELETE "$PLAYERPING_API/players/PLAYER_ID"




Events


| Method | Path | Purpose |

|--------|------|---------|

| GET | `/events` | List non-archived (`?archived=true` to include archived) |

| POST | `/events` | Create |

| GET | `/events/:id` | Get + responses (no tokens) |

| PATCH | `/events/:id` | Update |

| DELETE | `/events/:id` | Delete event and responses |


Create body


{

"date": "2026-09-01",

"time": "18:00",

"location": "Central Courts",

"sport": "Tennis",

"requiredPlayers": { "M": 2, "F": 2 },

"allowProposeTime": false,

"clubId": null

}


| Field | Required | Notes |

|-------|----------|-------|

| `date` | yes | ISO date / datetime |

| `time` | yes | e.g. `18:00` |

| `location` | yes | |

| `sport` | yes | |

| `requiredPlayers` | yes | object, typically gender → count |

| `allowProposeTime` | no | boolean |

| `clubId` | no | |

| `recurrence` | no | `{ "frequency": "weekly"\|"biweekly"\|"monthly", "endDate"?: "ISO", "count"?: 1-52 }` |


Patch fields


Partial update: `date`, `time`, `location`, `sport`, `status` (`OPEN`\|`PENDING`\|`CONFIRMED`\|`CANCELLED`), `requiredPlayers`, `allowProposeTime`, `archived` (past events only), `clubId`.


Examples


pp "$PLAYERPING_API/events"

pp -X POST "$PLAYERPING_API/events" -d '{"date":"2026-09-01","time":"18:00","location":"Central Courts","sport":"Tennis","requiredPlayers":{"M":2,"F":2}}'

pp "$PLAYERPING_API/events/EVENT_ID"

pp -X PATCH "$PLAYERPING_API/events/EVENT_ID" -d '{"status":"CONFIRMED"}'

pp -X DELETE "$PLAYERPING_API/events/EVENT_ID"




Players on an event (RSVPs)


Responses link a player to an event. Status values: `PENDING`, `YES`, `NO`, `MAYBE`, `WAITLIST`.


| Method | Path | Purpose |

|--------|------|---------|

| GET | `/events/:id/players` | List responses |

| POST | `/events/:id/players` | Add players |

| PATCH | `/events/:id/players/:playerId` | Set status |

| DELETE | `/events/:id/players/:playerId` | Remove from event |

| POST | `/events/:id/waitlist/:responseId/promote` | Waitlist → `YES` |


Add players body


{

"playerIds": ["cuid1", "cuid2"],

"notify": false,

"status": "PENDING"

}


  • `playerIds` — required non-empty array of player IDs owned by the key user.
  • `notify` — default behavior in this skill: false. `true` sends invitations per account notification settings; SMS/WhatsApp cost 1 credit each; email is free; insufficient credits → `402`.
  • `status` — only when `notify` is false. Defaults to `PENDING`.

Update status body


{ "status": "YES" }


Examples


pp "$PLAYERPING_API/events/EVENT_ID/players"

pp -X POST "$PLAYERPING_API/events/EVENT_ID/players" -d '{"playerIds":["PLAYER_ID"],"notify":false}'

pp -X PATCH "$PLAYERPING_API/events/EVENT_ID/players/PLAYER_ID" -d '{"status":"YES"}'

pp -X DELETE "$PLAYERPING_API/events/EVENT_ID/players/PLAYER_ID"

pp -X POST "$PLAYERPING_API/events/EVENT_ID/waitlist/RESPONSE_ID/promote"




Common workflows


Discover roster and upcoming events


  • `GET /players` — note IDs and sports.
  • `GET /events` — note IDs, dates, response counts.
  • `GET /events/:id` or `GET /events/:id/players` for RSVP detail.

Schedule a new session and add players (silent)


  • `POST /events` with date/time/location/sport/`requiredPlayers`.
  • Resolve player IDs via `GET /players` (match by name carefully; ask if ambiguous).
  • `POST /events/:id/players` with `notify: false`.
  • Optionally `PATCH .../players/:playerId` to set `YES` if the organizer already knows attendance.

Invite with notifications (costs credits)


  • Confirm with the user that SMS/WhatsApp may spend credits.
  • `POST /events/:id/players` with `{ "playerIds": [...], "notify": true }`.
  • Report `notificationsSent`, `creditsUsed`, `creditsRemaining` from the response.

Fix RSVPs / waitlist


  • `GET /events/:id/players` — find `WAITLIST` entries and their response `id`.
  • Promote: `POST /events/:id/waitlist/:responseId/promote`, or set status via PATCH.



Out of scope (v1)


Do not call these via this skill: clubs CRUD, ratings, chat, time proposals, AI endpoints, Stripe/credits purchase, Settings/API-key management (browser session only), admin APIs.


API keys are created/revoked by the human in Settings → API Keys. Point them to https://playerping.me/docs/api for human docs.


Response habits


  • Prefer concise summaries (counts, names, IDs, statuses) over dumping full JSON.
  • On errors, surface the HTTP status and `error` message, then suggest a fix (e.g. E.164 phone, missing fields, revoke/recreate key).
  • After mutating, re-fetch or echo the returned resource so the user can verify.