Mi Padel

API para clubes

Conecta la web de tu club o tu software de reservas con Mi Padel: consulta tus socios, tus partidos y tus torneos, y sincroniza las reservas de pista en los dos sentidos.

Esta API es solo para clubes. Las claves se crean desde el panel del club y pertenecen al club, no a una persona. No hay forma de que un jugador obtenga una, y una clave nunca ve datos de otro club. Se entrega a los clubes con el Plan Club activo: ver precios.

Cómo empezar

  1. Pide tu clave: el administrador del club la genera desde el panel.
  2. Guárdala en cuanto la veas. Solo se muestra una vez.
  3. Llama a GET /api/partner/v1/club para comprobar que funciona.

Autenticación

Cabecera Authorization con la clave como bearer. Nada de claves en la URL: acabarían en los registros de cualquier proxy por el que pase la petición.

curl https://mi-padel.com/api/partner/v1/club \
  -H "Authorization: Bearer mpk_9f3a1c02_TU_CLAVE"

OAuth 2.0, si lo prefieres

La misma clave sirve como cliente de OAuth (client_credentials): la cambias por un token de una hora y es el token el que viaja en las peticiones siguientes. Es lo que ya sabe hacer cualquier librería de OAuth, así que si usas una no tienes que programar nada especial.

curl -X POST https://mi-padel.com/api/oauth/token   -d grant_type=client_credentials   -d client_id=mpk_9f3a1c02   -d client_secret=mpk_9f3a1c02_TU_CLAVE

client_id es el prefijo y client_secret la clave entera. Con scope puedes pedir menos permisos de los que tiene la clave; pedir uno que no tenga devuelve invalid_scope, no un recorte silencioso. Si el club revoca la clave, sus tokens dejan de valer en la siguiente petición.

Los metadatos de descubrimiento están en oauth-authorization-server y oauth-protected-resource, y todo esto está explicado en auth.md.

La clave tiene esta forma:

mpk_9f3a1c02_dCJ3k...  →  mpk_9f3a1c02   parte pública, la ves en el panel
                          dCJ3k...        secreto, solo lo tienes tú
La clave va en tu servidor, nunca en el navegador. Si la pones en el JavaScript de la web del club, cualquiera que abra el inspector se la lleva y podrá leer todos los datos de tus socios. Si necesitas enseñar datos en la web pública, llama a la API desde tu backend y sirve tú el resultado.

Permisos

Cada clave lleva solo los permisos que le des. Da los mínimos: si la integración solo pinta la clasificación, no le des escritura.

PermisoPara qué
players_readLeer los socios del club
matches_readLeer los partidos
tournaments_readLeer los torneos
bookings_readLeer pistas y reservas
bookings_writeCrear pistas y reservas, y cancelarlas

Una clave sin el permiso recibe 403. Una clave inválida, revocada o caducada recibe 401, siempre con el mismo mensaje: no distinguimos entre esos casos a propósito.

Endpoints

Base: https://mi-padel.com/api/partner/v1

El club

GET /club
→ { "club": { "id", "slug", "name", "city", "timezone" },
    "scopes": ["players_read", ...] }

Útil para comprobar la clave y ver qué permisos tiene. No hace falta ninguno.

Socios

GET /members?limit=50&cursor=<uuid>        (players_read)
→ { "items": [{ "playerId", "displayName", "slug",
                "level", "role", "status", "joinedAt" }],
    "nextCursor": null }

level es el nivel de 0,50 a 7,00, o null mientras sea provisional. No se devuelven datos de contacto (ni correo, ni teléfono): esos datos ya los tiene el club por su cuenta, y sacarlos por aquí convertiría una clave filtrada en una fuga.

Partidos y torneos

GET /matches?from=2026-09-01T00:00:00Z&to=2026-09-30T00:00:00Z   (matches_read)
GET /tournaments?from=...&to=...                                (tournaments_read)

from y to son opcionales: por defecto son los próximos 30 días. Sin ventana se devolvería el histórico entero del club, que no le sirve a nadie y es caro para los dos lados.

Pistas y reservas

Las reservas están en preparación. Los endpoints están hechos y probados, pero hoy responden 404: Mi Padel todavía no reserva pistas. Están documentados aquí para que puedas preparar tu integración con antelación. Si te interesa, escríbenos y te avisamos al activarlos.
GET    /courts                       (bookings_read)
POST   /courts                       (bookings_write)
GET    /bookings?from=&to=&courtId=   (bookings_read)
POST   /bookings                     (bookings_write)
DELETE /bookings/{id}                (bookings_write)

Crear una reserva:

POST /bookings
{
  "courtId": "…",
  "startsAt": "2026-10-01T18:00:00Z",
  "endsAt":   "2026-10-01T19:30:00Z",
  "playerId": "…",              // opcional: socio de Mi Padel
  "contactName": "Invitado",    // opcional: si no hay socio
  "externalRef": "reserva-4711",// opcional pero MUY recomendable
  "notes": "Pista con luz"
}

Reintentar sin duplicar

Manda siempre externalRef con el identificador de la reserva en tu sistema. Si repites la petición (un timeout, un reintento de tu cola), no se crea una segunda reserva: se te devuelve la que ya existe con un 200 en vez de un 201. Así reintentar es seguro.

Dos reservas a la vez

El solape lo impide la base de datos, no una comprobación previa: dos peticiones simultáneas para la misma pista y hora no pueden ganar las dos. La que pierde recibe 409. Los tramos son [inicio, fin), así que 10:00–11:00 y 11:00–12:00 conviven sin problema.

Cancelar (DELETE) marca la reserva como cancelada y libera el hueco; no borra el registro.

Errores

Todos los errores siguen el formato problem details (RFC 9457), con Content-Type: application/problem+json:

{ "type": "about:blank", "title": "Conflict", "status": 409,
  "detail": "Esa pista ya esta reservada en ese horario" }
CódigoQué ha pasado
400Datos inválidos (fechas al revés, campos que faltan)
401Clave ausente, inválida, revocada o caducada
403La clave es válida pero no tiene ese permiso
404No existe, o no es de tu club, o la función está apagada
409Conflicto: solape de reserva, nombre de pista repetido
429Demasiadas peticiones: espera y reintenta

Un 404 en un recurso de otro club es deliberado: no confirmamos que exista algo que no es tuyo.

Buenas prácticas

¿Dudas?

Escríbenos desde el formulario de contacto contando qué quieres integrar. Si encuentras un problema de seguridad, está el /.well-known/security.txt.