API Documentation

Base URL: https://www.larpdatabase.com/api/v1

Introduction

larpdatabase.com collects and documents larp events, organizations, campaigns, crew and cast internationally.

The REST API v1 allows organizations to manage their content programmatically, integrating with their own tools and automating the operations normally performed through the management panel.

Through the API you can:

  • Create, update and delete draft events
  • Manage crew and cast of your events
  • Create, update and delete draft campaigns
  • Request publication of events and campaigns

Every organization contributing through the API helps us keep the larp database more complete and up to date.

Authentication

All API requests require a Bearer token. Generate one from your profile settings.

Authorization: Only organization owners and admins can use the API. Organization editors and regular members do not have API access.

Include these headers in every request:

Authorization: Bearer YOUR_API_TOKEN
Accept: application/json
Content-Type: application/json
Token Permissions
PermissionAccess
events:readRead events, crew, and cast
events:writeCreate, update, delete events, crew, and cast
campaigns:readRead campaigns
campaigns:writeCreate, update, delete campaigns
Token expiration: Tokens expire after 1 year. Generate a new one from your profile when needed.

Rate Limits

LimitValue
Requests per minute60
Event creation per day10
Campaign creation per day5

When a limit is exceeded, the API returns 429 Too Many Requests with a retry_after field.

Response Format

All responses follow a consistent JSON envelope:

{
    "success": true,
    "message": "OK",
    "data": { ... },
    "meta": { "current_page": 1, "last_page": 3, "per_page": 15, "total": 42 },
    "links": { "first": "...", "last": "...", "prev": null, "next": "..." }
}

meta and links are only present in paginated responses (list endpoints).

Error Codes

CodeMeaningExample
401UnauthenticatedMissing or invalid token
403ForbiddenToken lacks required permission or not team admin
404Not FoundResource does not exist or belongs to another team
409ConflictTrying to delete a published resource
422Validation ErrorInvalid or missing fields
429Too Many RequestsRate limit exceeded

Validation errors include a detailed errors object:

{
    "success": false,
    "message": "Validation failed.",
    "errors": {
        "nome": ["The nome field is required."],
        "data_fine": ["The data fine must be after or equal to data inizio."]
    }
}

Reference

GET /genres Public

Returns a list of all available event genres.

This endpoint does not require authentication and is mounted at /api/v1/genres.

Example
curl -X GET "https://www.larpdatabase.com/api/v1/genres" \
  -H "Accept: application/json"
Response Example
{
    "success": true,
    "data": [
        { "id": 1, "name": "Fantasy", "name_en": "Fantasy" },
        { "id": 2, "name": "Fantascienza", "name_en": "Sci-Fi" }
    ]
}

Events

GET /teams/{team}/events

Returns a paginated list of events for the team.

Query Parameters
ParamTypeDescription
statusstringFilter by status: draft, pending, published
pageintegerPage number (default: 1)
Example
curl -X GET "https://www.larpdatabase.com/api/v1/teams/1/events?status=draft" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Required permission: events:read

POST /teams/{team}/events

Creates a new event in draft status.

Body Parameters
FieldTypeRequiredDescription
nomestringYesEvent name (max 255)
abstractstringNoDescription in Italian (max 5000)
abstract_enstringNoDescription in English (max 5000)
generearrayYesArray of genre IDs (at least one required)
tipologiastringYesEvent category. Allowed values: one shot, serie, campagna, edu larp, convention, altro, chamber larp, laog
runstringYesRun number (max 50)
linguaarrayYesLanguages (at least one required). Allowed values: it, en, fr, es, de, sl, zh, hu, pl, nl, bg, el
data_iniziodateYesStart date (YYYY-MM-DD)
data_finedateYesEnd date (YYYY-MM-DD, must be >= data_inizio)
durataintegerYesDuration value
tipo_duratastringYesDuration type. Allowed values: ore, giorni
numero_partecipantiintegerYesNumber of participants (1-100000)
tipo_eventostringNoEvent type. Allowed values: atti, continuativo
costonumberNoMinimum cost (0-99999.99)
costo_maxnumberNoMaximum cost (must be >= costo)
locationstringNoCoordinates as lat,lng
nome_locationstringNoLocation name (max 255)
luogostringNoCity/Place (max 255)
nazionestringNoCountry (max 100)
accommodationstringNoAccommodation type. Allowed values: compresa, non compresa, non residenziale
tipo_accommodationarrayNoAccommodation details. Allowed values: campeggio, agriturismo, residenza d'epoca, hotel, altro
pastiarrayNoMeals included. Allowed values: non compresi, ristorante, fai da te, catering interno, catering esterno
sito_eventourlNoEvent website (max 500)
campagna_idintegerNoCampaign ID to link to
organizzazioni_aggiuntivearrayNoAdditional organization IDs
locandinafileNoPoster image (jpeg/png/webp, max 5MB). Use multipart/form-data.
Example
curl -X POST "https://www.larpdatabase.com/api/v1/teams/1/events" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "The Great larp",
    "abstract": "An epic adventure...",
    "genere": [1, 3],
    "tipologia": "one shot",
    "run": "1",
    "lingua": ["it", "en"],
    "data_inizio": "2026-07-01",
    "data_fine": "2026-07-03",
    "durata": 3,
    "tipo_durata": "giorni",
    "numero_partecipanti": 50,
    "costo": 100,
    "location": "41.9028,12.4964"
  }'

Required permission: events:write | Subject to daily creation limit

GET /teams/{team}/events/{event}

Returns a single event by ID. The event must belong to the specified team.

Required permission: events:read

PUT /teams/{team}/events/{event}

Updates an existing event. Only send the fields you want to change. Accepts application/json.

Accepts the same fields as Create Event, except locandina. To manage the poster image use the dedicated endpoints below.

Example
curl -X PUT "https://www.larpdatabase.com/api/v1/teams/1/events/123" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"nome": "Updated Title", "costo": 120}'

Required permission: events:write

POST /teams/{team}/events/{event}/locandina

Uploads or replaces the poster image for an event. Send as multipart/form-data.

Body Parameters
FieldTypeRequiredDescription
locandinafileYesPoster image (jpeg/png/webp, max 5 MB)
Example
curl -X POST "https://www.larpdatabase.com/api/v1/teams/1/events/123/locandina" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -F "locandina=@/path/to/poster.jpg"

Required permission: events:write

DELETE /teams/{team}/events/{event}/locandina

Removes the poster image from an event.

Example
curl -X DELETE "https://www.larpdatabase.com/api/v1/teams/1/events/123/locandina" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Required permission: events:write

DELETE /teams/{team}/events/{event}

Deletes an event. Only draft events can be deleted. Returns 409 for non-draft events.

Required permission: events:write

POST /teams/{team}/events/{event}/request-publish

Submits a draft event for review. Changes status from draft to pending. Only works on draft events.

Required permission: events:write

Crew

UUID-based identification: Each crew member is identified by a uuid field (e.g. 550e8400-e29b-41d4-a716-446655440000). Store this UUID in your system when inserting a crew member — use it as the {crew} parameter in PUT, DELETE, and reorder calls. Internal numeric IDs are never exposed.
GET /teams/{team}/events/{event}/crew

Returns all crew members for an event, ordered by sort_order.

Response Example
{
    "success": true,
    "data": [
        {
            "uuid": "550e8400-e29b-41d4-a716-446655440000",
            "entity_type": "person",
            "first_name": "Mario",
            "last_name": "Rossi",
            "role": "Director",
            "user_id": null,
            "is_organizer": true,
            "sort_order": 0,
            "evento_id": 123,
            "created_at": "2026-04-29T10:00:00+00:00",
            "updated_at": "2026-04-29T10:00:00+00:00"
        }
    ]
}

Required permission: events:read

POST /teams/{team}/events/{event}/crew

Adds a crew member to an event. The response includes the uuid assigned — store it to use in future PUT/DELETE/reorder calls.

Body Parameters
FieldTypeRequiredDescription
entity_typestringYesperson or company
first_namestringIf personFirst name (max 255)
last_namestringIf personLast name (max 255)
rolestringYesRole (e.g. Director, Designer, Writer)
is_organizerbooleanYesWhether this person is an organizer
user_idintegerNoLink to existing user account
sort_orderintegerNoDisplay order
Example
curl -X POST "https://www.larpdatabase.com/api/v1/teams/1/events/123/crew" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "entity_type": "person",
    "first_name": "Mario",
    "last_name": "Rossi",
    "role": "Director",
    "is_organizer": true
  }'
Response Example
{
    "success": true,
    "message": "Crew member added successfully.",
    "data": {
        "uuid": "550e8400-e29b-41d4-a716-446655440000",
        "entity_type": "person",
        "first_name": "Mario",
        "last_name": "Rossi",
        "role": "Director",
        "user_id": null,
        "is_organizer": true,
        "sort_order": 0,
        "evento_id": 123,
        "created_at": "2026-04-29T10:00:00+00:00",
        "updated_at": "2026-04-29T10:00:00+00:00"
    }
}

Required permission: events:write

PUT /teams/{team}/events/{event}/crew/{crew}

Updates a crew member. Only send the fields you want to change. Same fields as Add Crew.

{crew} is the uuid returned when the crew member was created.

Example
curl -X PUT "https://www.larpdatabase.com/api/v1/teams/1/events/123/crew/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"role": "Co-Director"}'

Required permission: events:write

DELETE /teams/{team}/events/{event}/crew/{crew}

Removes a crew member from the event.

{crew} is the uuid returned when the crew member was created.

Example
curl -X DELETE "https://www.larpdatabase.com/api/v1/teams/1/events/123/crew/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Required permission: events:write

PUT /teams/{team}/events/{event}/crew/reorder

Reorders crew members for an event. Pass an array of uuid + sort_order pairs.

Example
curl -X PUT "https://www.larpdatabase.com/api/v1/teams/1/events/123/crew/reorder" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "order": [
      {"uuid": "550e8400-e29b-41d4-a716-446655440000", "sort_order": 0},
      {"uuid": "661f9511-f30c-52e5-b827-557766551111", "sort_order": 1},
      {"uuid": "772a0622-g41d-63f6-c938-668877662222", "sort_order": 2}
    ]
  }'

Required permission: events:write

Cast

UUID-based identification: Each cast member is identified by a uuid field (e.g. 550e8400-e29b-41d4-a716-446655440000). Store this UUID in your system when inserting a participant — use it as the {participant} parameter in all subsequent PUT and DELETE calls. Internal numeric IDs are never exposed.
GET /teams/{team}/events/{event}/cast

Returns all cast members for an event.

Response Example
{
    "success": true,
    "data": [
        {
            "uuid": "550e8400-e29b-41d4-a716-446655440000",
            "first_name": "Luca",
            "last_name": "Bianchi",
            "character": "King Aldric",
            "npc": false,
            "user_id": null,
            "evento_id": 123,
            "created_at": "2026-04-29T10:00:00+00:00",
            "updated_at": "2026-04-29T10:00:00+00:00"
        }
    ]
}

Required permission: events:read

POST /teams/{team}/events/{event}/cast

Adds a cast member to an event. The response includes the uuid assigned to the new participant — store it to use in future PUT/DELETE calls.

Body Parameters
FieldTypeRequiredDescription
first_namestringYesFirst name (max 255)
last_namestringYesLast name (max 255)
characterstringYesCharacter name (max 255)
npcbooleanNoIs this an NPC? (default: false)
user_idintegerNoLink to existing user account
Example
curl -X POST "https://www.larpdatabase.com/api/v1/teams/1/events/123/cast" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Luca",
    "last_name": "Bianchi",
    "character": "King Aldric",
    "npc": false
  }'
Response Example
{
    "success": true,
    "message": "Cast member added successfully.",
    "data": {
        "uuid": "550e8400-e29b-41d4-a716-446655440000",
        "first_name": "Luca",
        "last_name": "Bianchi",
        "character": "King Aldric",
        "npc": false,
        "user_id": null,
        "evento_id": 123,
        "created_at": "2026-04-29T10:00:00+00:00",
        "updated_at": "2026-04-29T10:00:00+00:00"
    }
}

Required permission: events:write

PUT /teams/{team}/events/{event}/cast/{participant}

Updates a cast member. Only send the fields you want to change. Same fields as Add Cast.

{participant} is the uuid returned when the cast member was created.

Example
curl -X PUT "https://www.larpdatabase.com/api/v1/teams/1/events/123/cast/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"character": "King Aldric the Bold"}'

Required permission: events:write

DELETE /teams/{team}/events/{event}/cast/{participant}

Removes a cast member from the event.

{participant} is the uuid returned when the cast member was created.

Example
curl -X DELETE "https://www.larpdatabase.com/api/v1/teams/1/events/123/cast/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json"

Required permission: events:write

Campaigns

GET /teams/{team}/campaigns

Returns a paginated list of campaigns for the team.

Query Parameters
ParamTypeDescription
statusstringFilter by status: draft, pending, published
pageintegerPage number (default: 1)

Required permission: campaigns:read

POST /teams/{team}/campaigns

Creates a new campaign in draft status.

Body Parameters
FieldTypeRequiredDescription
titolostringYesCampaign title (max 255)
descrizionestringNoDescription (max 10000)
statostringYesCampaign status. Allowed values: In corso, Conclusa
anno_iniziointegerYesStart year (1900-current year)
organizzazioni_aggiuntivearrayNoAdditional organization IDs
locandinafileNoPoster image (jpeg/png/webp, max 5MB). Use multipart/form-data.
Example
curl -X POST "https://www.larpdatabase.com/api/v1/teams/1/campaigns" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "titolo": "The Great Campaign",
    "descrizione": "An epic multi-year adventure",
    "anno_inizio": 2026
  }'

Required permission: campaigns:write | Subject to daily creation limit

GET /teams/{team}/campaigns/{campaign}

Returns a single campaign by ID.

Required permission: campaigns:read

PUT /teams/{team}/campaigns/{campaign}

Updates a campaign. Only send the fields you want to change. Same fields as Create Campaign, plus:

FieldTypeDescription
remove_current_imagebooleanSet to true to remove the current poster

Required permission: campaigns:write

DELETE /teams/{team}/campaigns/{campaign}

Deletes a campaign. Only draft campaigns can be deleted. Returns 409 for non-draft campaigns.

Required permission: campaigns:write

POST /teams/{team}/campaigns/{campaign}/request-publish

Submits a draft campaign for review. Changes status from draft to pending.

Required permission: campaigns:write