Naar de inhoud

Referentie

Organisator

Je eigen events: aantallen, externe verkoop, ticketlijsten en de scanner aan de deur.

Your own events: attendance, external sales and the door scanner.

De beschrijvingen van de endpoints komen uit de specificatie en zijn in het Engels.

GET/events/{id}/attendance

Attendance of your event

Toegang
Token met attendance
operationId
getAttendance

How many people said "Ik ga", how many marked interest and how many tickets were sold through PartyPPL, exact; and who is coming as groups (returning, province, age, genres), never a group under ten. Only for events of the token's own organisation.

Parameters

NaamInTypeStandaardUitleg
id verplichtpathstring-The id of the resource. Events also accept their slug.

Voorbeeldverzoek

curl
curl -s "https://api.partyppl.nl/v1/events/oost-sat/attendance" \
  -H "Authorization: Bearer $PPL_TOKEN"
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/events/oost-sat/attendance", {
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.get(
    "https://api.partyppl.nl/v1/events/oost-sat/attendance",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "eventId": "oost-sat",
    "counts": {
      "going": 412,
      "interested": 88,
      "tickets": 260
    },
    "audience": {
      "computed_at": 1790000000,
      "min_cell": 10,
      "total": 520,
      "returning": 185,
      "new": 335,
      "returning_share": 36,
      "regions": {
        "rows": [
          {
            "key": "Noord-Holland",
            "count": 290
          },
          {
            "key": "Utrecht",
            "count": 95
          }
        ],
        "other": 105,
        "hidden": 4
      },
      "ages": {
        "rows": [
          {
            "key": "21-24",
            "count": 180
          },
          {
            "key": "25-29",
            "count": 150
          }
        ],
        "other": 160,
        "hidden": 3
      },
      "genres": {
        "rows": [
          {
            "key": "Techno",
            "count": 310
          }
        ],
        "other": null,
        "hidden": 0
      }
    }
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200Attendance of your event
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the attendance scope, or the organisation is suspended.
  • 404No such resource.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

GET/events/{id}/external-sales

Read the external sales count

Toegang
Token met attendance
operationId
getExternalSales

The number of tickets you last reported as sold through your own shop for this event.

Parameters

NaamInTypeStandaardUitleg
id verplichtpathstring-The id of the resource. Events also accept their slug.

Voorbeeldverzoek

curl
curl -s "https://api.partyppl.nl/v1/events/oost-sat/external-sales" \
  -H "Authorization: Bearer $PPL_TOKEN"
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/events/oost-sat/external-sales", {
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.get(
    "https://api.partyppl.nl/v1/events/oost-sat/external-sales",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "eventId": "oost-sat",
    "external": true,
    "sold": 340,
    "updatedAt": 1758499200
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200Read the external sales count
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the attendance scope, or the organisation is suspended.
  • 404No such resource.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

POST/events/{id}/external-sales

Report the external sales count

Toegang
Token met attendance
operationId
setExternalSales

Tell us how many tickets your own shop has sold for this event, so the event page and your dashboard can show the real number. Only for events with external ticketing.

Parameters

NaamInTypeStandaardUitleg
id verplichtpathstring-The id of the resource. Events also accept their slug.

Body (JSON)

NaamTypeStandaardUitleg
sold verplichtinteger0..10000000-Tickets sold so far, a whole number of 0 or more.

Voorbeeldverzoek

curl
curl -s -X POST "https://api.partyppl.nl/v1/events/oost-sat/external-sales" \
  -H "Authorization: Bearer $PPL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sold":340}'
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/events/oost-sat/external-sales", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "sold": 340
  }),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.post(
    "https://api.partyppl.nl/v1/events/oost-sat/external-sales",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    json={
        "sold": 340,
    },
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "eventId": "oost-sat",
    "external": true,
    "sold": 340,
    "updatedAt": 1758499200
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200Report the external sales count
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the attendance scope, or the organisation is suspended.
  • 404No such resource.
  • 409This event does not use external ticketing.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

POST/scan

Scan a ticket at the door

Toegang
Token met scan
operationId
scanTicket

Validate a ticket QR and mark it used. A refused ticket comes back as 200 with ok false and a reason, because the door needs the reason on screen; only a broken request is an error. Same rules as the door page in the organiser portal.

Body (JSON)

NaamTypeStandaardUitleg
code verplichtstring-The ticket code, or the whole scanned URL containing /t/<code>.
eventId optioneelstring-Refuse tickets that are not for this event. Leave it out to accept any ticket of your organisation.

Voorbeeldverzoek

curl
curl -s -X POST "https://api.partyppl.nl/v1/scan" \
  -H "Authorization: Bearer $PPL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"code":"PPL-A1B2-C3D4-E5F6","eventId":"oost-sat"}'
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/scan", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "code": "PPL-A1B2-C3D4-E5F6",
    "eventId": "oost-sat"
  }),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.post(
    "https://api.partyppl.nl/v1/scan",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    json={
        "code": "PPL-A1B2-C3D4-E5F6",
        "eventId": "oost-sat",
    },
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "status": "ok",
    "title": "Jesse · Regular",
    "sub": "Gescand 23:14",
    "type": "Regular",
    "holder": "Jesse",
    "eventId": "oost-sat",
    "scannedAt": 1758499200
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200Scan a ticket at the door
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the scan scope, or the organisation is suspended.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

GET/events/{id}/external-tickets

What became of the delivered tickets

Toegang
Token met tickets
operationId
getExternalTickets

Per event: how many tickets were delivered, how many are on a member's account, how many wait for somebody with that address to log in, and how many still have to be processed (a mail to send). Plus the last twenty deliveries.

Parameters

NaamInTypeStandaardUitleg
id verplichtpathstring-The id of the resource. Events also accept their slug.

Voorbeeldverzoek

curl
curl -s "https://api.partyppl.nl/v1/events/oost-sat/external-tickets" \
  -H "Authorization: Bearer $PPL_TOKEN"
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/events/oost-sat/external-tickets", {
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
  },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.get(
    "https://api.partyppl.nl/v1/events/oost-sat/external-tickets",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "eventId": "oost-sat",
    "counts": {
      "delivered": 340,
      "linked": 212,
      "pending": 128,
      "todo": 0
    },
    "batches": [
      {
        "id": "xb_2a91f0c4e3b7d8a1f6c2",
        "source": "eventix",
        "via": "api",
        "received": 340,
        "added": 340,
        "duplicates": 0,
        "refused": 0,
        "linked": 212,
        "createdAt": 1758499200
      }
    ]
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200What became of the delivered tickets
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the tickets scope, or the organisation is suspended.
  • 404No such resource.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

POST/events/{id}/external-tickets

Deliver the ticket list of your own shop

Toegang
Token met tickets
operationId
deliverExternalTickets

Hand over the tickets another shop (Eventix, Paylogic, Ticketmaster, your own) sold for this event, so each one lands on the PartyPPL account of the person who bought it: the same barcode under Tickets, scannable at the door, and the buyer listed as going. An address that has no account yet gets one mail saying the ticket is waiting (unless invite is false), and the ticket attaches itself the moment that address logs in. Idempotent on the code: send the same export again and nothing is added twice. Every item is answered separately; only a request that is wrong as a whole is refused. What is kept of an address: an HMAC of it and, until the one mail went out, the address itself.

Parameters

NaamInTypeStandaardUitleg
id verplichtpathstring-The id of the resource. Events also accept their slug.

Body (JSON)

NaamTypeStandaardUitleg
source optioneeleventix | paylogic | ticketmaster | weezevent | other"other"The shop that sold them. Shown on the ticket ("via Eventix") and at the door.
invite optioneelbooleantrueWhether an address without an account gets the mail that says its ticket is waiting. Members are always notified.
items verplichtobject[]max 500 items-The tickets, at most 500 per call. Every item comes back in results with its own verdict: added (with whether the address is a member), duplicate (this code was delivered before for this event) or refused with the reason.

Velden van één item: items[]

NaamTypeStandaardUitleg
email verplichtstringmax 254 chars-The buyer's address. Matched exactly after trimming and lowercasing.
code verplichtstringmax 64 chars-The barcode or ticket code as the shop's scanner reads it. Unique across everything.
type optioneelstringmax 60 chars-The ticket type. "Ticket" when absent.
name optioneelstringmax 80 chars-The name on the ticket.
price optioneelnumber>= 0-What it cost, for the organiser's own overview. Never charged again.

Voorbeeldverzoek

curl
curl -s -X POST "https://api.partyppl.nl/v1/events/oost-sat/external-tickets" \
  -H "Authorization: Bearer $PPL_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"source":"eventix","invite":true,"items":[{"email":"jesse@example.com","code":"EVX-8F3K2-91","type":"Early Bird","name":"Jesse Bos","price":27.5}]}'
JavaScript
const res = await fetch("https://api.partyppl.nl/v1/events/oost-sat/external-tickets", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PPL_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "source": "eventix",
    "invite": true,
    "items": [
      {
        "email": "jesse@example.com",
        "code": "EVX-8F3K2-91",
        "type": "Early Bird",
        "name": "Jesse Bos",
        "price": 27.5
      }
    ]
  }),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data, meta } = await res.json();
Python
import os
import requests

res = requests.post(
    "https://api.partyppl.nl/v1/events/oost-sat/external-tickets",
    headers={"Authorization": f"Bearer {os.environ['PPL_TOKEN']}"},
    json={
        "source": "eventix",
        "invite": True,
        "items": [
            {
                "email": "jesse@example.com",
                "code": "EVX-8F3K2-91",
                "type": "Early Bird",
                "name": "Jesse Bos",
                "price": 27.5,
            },
        ],
    },
    timeout=30,
)
res.raise_for_status()
payload = res.json()
Toon het voorbeeldantwoord
200 · Voorbeeldantwoord
{
  "data": {
    "ok": true,
    "batchId": "xb_2a91f0c4e3b7d8a1f6c2",
    "eventId": "oost-sat",
    "results": [
      {
        "index": 0,
        "code": "EVX-8F3K2-91",
        "status": "added",
        "member": true
      },
      {
        "index": 1,
        "code": "EVX-8F3K2-92",
        "status": "duplicate"
      },
      {
        "index": 2,
        "code": "X",
        "status": "refused",
        "reason": "invalid_code"
      }
    ],
    "totals": {
      "received": 3,
      "added": 1,
      "duplicates": 1,
      "refused": 1,
      "matched": 1
    },
    "processed": {
      "linked": 1,
      "mailed": 1,
      "skipped": 0,
      "failed": 0,
      "left": 0,
      "budgetOut": false
    }
  },
  "meta": {
    "request_id": "9f1c2b4a-7e3d-4a10-9c2f-6b8d1e5a0c33"
  }
}

Statussen

  • 200Deliver the ticket list of your own shop
  • 400The request is wrong. error.details.params names every bad parameter.
  • 401No token, or a token we do not know.
  • 403The token is valid but does not carry the tickets scope, or the organisation is suspended.
  • 404No such resource.
  • 429Over the per-minute limit or the daily quota. Retry-After says how long to wait.
  • 500Something went wrong on our side. Quote request_id.

De specificatie als JSON