> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rocky.global/llms.txt
> Use this file to discover all available pages before exploring further.

# Organizer api

# Organizer API

This document collects and standardizes the API documentation for Organizers.

## Authentication

* Bearer Token (Sanctum Personal Access Tokens)
* Required scope: `organizer-api`
* Access restricted to the `organizador_id` of the token owner

### Supervisor

* Bearer Token (Sanctum Personal Access Tokens)
* Required scope: `supervisor-api`
* Access to participants of all events

## Rate limiting

* RateLimiter: `organizer-api`
* Default value: 60 req/min, configurable per organizer

## Endpoints

### GET /api/v1/organizer/participants

Retrieves participants from the authenticated organizer's events.

### GET /api/v1/supervisor/participants

Retrieves participants from all events (requires Supervisor or Administrator role).

Parameters (query): same as the organizer's.

Cursor pagination (recommended for large volumes):

* `pagination=cursor` enables cursor pagination.
* `per_page` page size (recommended 1000–2000 for 20k+).
* Response includes `meta.cursor.next_cursor` and `meta.cursor.prev_cursor`.
* With cursor, only `order_by=id` is allowed.

Examples:

```bash theme={null}
# Get all participants
curl -H "Authorization: Bearer <TOKEN_SUPERVISOR>" "https://TU_DOMINIO/api/v1/supervisor/participants?per_page=2000"

# First page with cursor (recommended)
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  "https://TU_DOMINIO/api/v1/supervisor/participants?pagination=cursor&per_page=2000"

# Next page with cursor
curl -H "Accept: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  "https://TU_DOMINIO/api/v1/supervisor/participants?pagination=cursor&per_page=2000&cursor=<NEXT_CURSOR>"
```

Parameters (query):

* `participant_id` (optional, integer) - Filter by a specific participant ID
* `event_id` (optional, integer) - Filter by event ID
* `status` (optional, string) - Filter by participant status
* `bib` (optional, string) - Filter by BIB number
* `from` (optional, Y-m-d) - Start date to filter by creation date
* `to` (optional, Y-m-d) - End date to filter by creation date
* `search` (optional, string) - Search by name, last name, email, phone, locator, notes
* `order_by` (optional, string) - Sort field: id|created\_at|status|bib|evento\_id
* `order_dir` (optional, string) - Sort direction: asc|desc
* `per_page` (optional, integer) - Number of items per page (respects configuration limits)

Response: collection of `ParticipantResource` with `meta.filters`.

Examples:

```bash theme={null}
# Get all participants
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?per_page=50"

# Get a specific participant by ID
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?participant_id=123"

# Filter by a specific event
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?event_id=456"

# Combine filters
curl -H "Authorization: Bearer <TOKEN>" "https://TU_DOMINIO/api/v1/organizer/participants?event_id=456&status=active&per_page=20"
```

## Per-organizer configuration

Table: `organizer_api_settings`

* `enabled`
* `rate_limit_per_minute`
* `default_page_size`
* `max_page_size`
* `ip_allowlist`

## Roadmap

* New endpoints under `/api/v1/organizer/*`
* Versioning via header or v2 prefix
* Auto-generated OpenAPI/Swagger

### POST /api/v1/organizer/participants

Updates participants by id (bulk, batched). Only non-autogenerated fields are allowed.

### POST /api/v1/supervisor/participants

Updates participants by id (bulk, batched). Only non-autogenerated fields are allowed. Requires Supervisor or Administrator role and `supervisor-api` scope.

Bulk upload (best practices):

* Large batches are accepted (e.g. 20k). If the `updates` array exceeds 1000 elements, the server splits it into chunks and processes them in the background via the queue.
* Immediate response with `202 Accepted` and chunk metadata. Check the logs to see progress.
* Sizes ≤1000 are processed synchronously with a 200 response.

Body (JSON) and response: same as the organizer endpoint.

cURL example:

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  -d '{
    "updates": [
      {"id": 123, "bib": "A-102"},
      {"id": 124, "observations": "Nota"}
    ]
  }' \
  "https://TU_DOMINIO/api/v1/supervisor/participants"
```

Bulk example (will receive 202 Accepted):

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN_SUPERVISOR>" \
  -d @payload_20000.json \
  "https://TU_DOMINIO/api/v1/supervisor/participants"
```

* Authorization: Bearer Token (Sanctum) with `organizer-api` scope.
* Roles: Organizer or Administrator.
* Additional security: Optional `X-Organizer-Id` header to reinforce ownership.
* Validations: JSON only; suspicious content is rejected (script, javascript:, on\* handlers, data:text/html) in the `competition_results` and `details` objects.

Fields allowed per participant:

* `bib` (String, optional) - Participant's BIB number
* `observations` (String, optional) - General observations about the participant
* `participation_notes` (String, optional) - Specific participation notes
* `competition_results` (JSON Object, optional) - Competition results in JSON format
* `details` (JSON Object, optional) - Additional participant details in JSON format

Prohibited fields (rejected): `evento_id`, `locator`, `order_id`, `user_id`, `created_by`, `updated_by`, `deleted_by`, `status`.

Body (JSON):

```json theme={null}
{
  "updates": [
    {
      "id": 123,
      "bib": "A-102",
      "observations": "Llegó con retraso de 2m",
      "participation_notes": "Usa chip nuevo",
      "competition_results": {
        "tiempo_chip": "00:45:12",
        "posicion_final": 12
      },
      "details": {
        "talla": "M"
      }
    },
    { "id": 124, "observations": "Nota actualizada" }
  ]
}
```

Response 200:

```json theme={null}
{
  "data": [
    { "id": 123, "updated": true },
    { "id": 124, "updated": false, "message": "No se enviaron campos actualizables" }
  ],
  "errors": [
    { "id": 999, "code": "ORGAPI_404_NOT_FOUND", "message": "Participante no encontrado" }
  ],
  "meta": { "updated_count": 1, "failed_count": 1 }
}
```

cURL example:

```bash theme={null}
curl -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <TOKEN>" \
  -H "X-Organizer-Id: <ID_ORGANIZADOR>" \
  -d '{
    "updates": [
      {"id": 123, "bib": "A-102"},
      {"id": 124, "observations": "Nota"}
    ]
  }' \
  "https://TU_DOMINIO/api/v1/organizer/participants"
```
