-
-
Notifications
You must be signed in to change notification settings - Fork 348
REST API v1
While we're working on exposing all Alf.io functionalities through APIs (this will happen in v2) we decided to develop a very simple API for creating / updating / deleting and retrieving event statistics.
Configuration
Event
- Create
- Update
- List Subscriptions linked to Event
- Link Subscriptions to Event
- Generate tickets for subscribers
- Check-in log
- Delete
- JSON Reference
Reservation
- Create Ticket Reservation
- Create Subscription Reservation
- Get Reservation Detail
- Confirm Reservation
- Remove Ticket
- Cancel Subscription
Subscription Descriptor
- List Organizations
- Get Organization
- Create Organization
- Update Organization
- Delete Organization
- Create API Key for Organization
- Delete API Key
You must specify an API Client ApiKey in order to call the APIs.
curl -X POST http://localhost:8080/api/v1/admin/event/create \
-H "Authorization: ApiKey e210468a-1831-4cf2-93d8-8cc093c7bd7d" \
-H "Cache-Control: no-cache" -H "Content-Type: application/json" \
-d "REQUEST_BODY_JSON (see below)"
ApiKey can be:
- A system API Key for system-level requests (i.e. create a new organization)
- An organization-level API Key for creating events and creating reservations
You can create an organization-level API Key from your Alf.io instance. Select "API Key" from the top menu and then fill in the details.
Only the "admin" user can view and rotate the System API Key. Select "API Key" from the top menu. You'll see
in order to consume this APIs you must generate a Organization-level API Key
PUT /api/v1/admin/configuration/organization/{organizationId}
{
"USE_INVOICE_NUMBER_AS_ID": "true",
"VAT_NUMBER_IS_REQUIRED": "true",
"ENABLE_ITALY_E_INVOICING": "true",
"GENERATE_ONLY_INVOICE": "true",
"ITALY_E_INVOICING_SEND_PROFORMA": "true"
}
PUT /api/v1/admin/configuration/organization/{organizationId}/event/{slug}
{
"USE_INVOICE_NUMBER_AS_ID": "true",
"VAT_NUMBER_IS_REQUIRED": "true",
"ENABLE_ITALY_E_INVOICING": "true",
"GENERATE_ONLY_INVOICE": "true",
"ITALY_E_INVOICING_SEND_PROFORMA": "true"
}
PUT /api/v1/admin/configuration/organization/{organizationId}/subscription/{id}
{
"USE_INVOICE_NUMBER_AS_ID": "true",
"VAT_NUMBER_IS_REQUIRED": "true",
"ENABLE_ITALY_E_INVOICING": "true",
"GENERATE_ONLY_INVOICE": "true",
"ITALY_E_INVOICING_SEND_PROFORMA": "true"
}
POST /api/v1/admin/event/create
Sample Body (Reference)
{
"title": "Titolo",
"slug": "titolo",
"description": [{
"lang": "de",
"body": "text description"
}],
"location": {
"fullAddress": "Pollegio 6742 Switzerland",
"coordinate": {
"latitude": "45.55",
"longitude": "9.00"
}
},
"timezone": "Europe/Zurich",
"startDate": "2018-08-12T08:00:00",
"endDate": "2018-08-12T09:00:00",
"websiteUrl": "http://www.amicidelticino.ch/aktivitaten/exklusivbesuch-des-kommandoturms-der-sbb",
"termsAndConditionsUrl": "http://www.amicidelticino.ch/agb",
"imageUrl": "https://www.amicidelticino.ch/assets/adt/images/amicidelticino-logo.png",
"tickets": {
"freeOfCharge": false,
"max": 10,
"currency": "CHF",
"taxPercentage": 7.7,
"taxIncludedInPrice": true,
"paymentMethods": ["ON_SITE"],
"categories": [
{
"name":"Standard",
"description": [{
"lang": "de",
"body": "text description"
}],
"maxTickets": null,
"accessRestricted": false,
"price": 10.0,
"startSellingDate": "2018-08-02T15:24:22",
"endSellingDate": "2018-08-12T07:00:00",
"groupLink": {
"groupId": 123,
"type": "LIMITED_QUANTITY",
"matchType": "EMAIL_DOMAIN",
"maxAllocation": 2
}
}
]
},
"extensionSettings": [{
"extensionId": "mailchimp",
"key":"listId",
"value":"your-list-id"
}]
}
- HTTP 200 {slug} - the given slug or a new, auto-generated one
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/event/update/{slug}
Sample Body (Reference)
{
"title": "NewTitle",
"startDate": "2018-08-12T08:01:00"
}
- HTTP 200 {slug}
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
GET /api/v1/admin/event/{slug}/subscriptions
- HTTP 200 Array of LinkedSubscription
- HTTP 404 Event not found
PUT /api/v1/admin/event/{slug}/subscriptions
[
{
"descriptorId": "33bd5a7b-5bbf-4040-818b-c7e4c7490312",
"categories": [ 1, 2 ]
}
]
- HTTP 200 List of linked subscriptions
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
Triggers ticket generation for subscription holders linked to a given event
POST /api/v1/admin/event/{slug}/generate-subscribers-tickets
{}
-
HTTP 200
true
if generation job has been scheduled - HTTP 400 Error descriptor
- HTTP 500 Error descriptor
Returns the check-in log for a given Event
GET /api/v1/admin/event/{slug}/check-in-log
- HTTP 200 List of CheckInLogEntry
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
DELETE /api/v1/admin/event/{slug}
- HTTP 200 OK
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/event/{slug}/reservation
Sample Body (Reference)
{
"tickets": [
{
"ticketCategoryId": 53,
"quantity": "1",
"attendees": [{
"firstName": "Test",
"lastName": "McTest",
"email": "[email protected]",
"metadata": {
"attributeForTicket1": "value"
}
}]
},
{
"ticketCategoryId": 56,
"quantity": "2",
"attendees": [{
"firstName": "John",
"lastName": "Doe",
"email": "[email protected]",
"metadata": {
"attributeForTicket1": "value1"
}
},{
"firstName": "Jane",
"lastName": "Doe",
"email": "[email protected]",
"metadata": {
"attributeForTicket2": "value2"
}
}]
}
],
"additionalServices": [
{
"additionalServiceId": 1,
"quantity": 1
}
],
"promoCode": null,
"user": {
"username": "[email protected]",
"firstName": "Test",
"lastName": "McTest",
"email": "[email protected]",
"id": "external-id"
},
"configuration": {
"hideContactData": false
}
}
-
HTTP 201
{ "success": true, "id": "reservation-id", "href": "public-url-for-reservation", "errors": null }
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/subscription/{descriptorId}/reservation
Sample Body (Reference)
{
"metadata": {
"key1": "value1"
},
"user": {
"username": "[email protected]",
"firstName": "Test",
"lastName": "McTest",
"email": "[email protected]"
},
"configuration": {
"hideContactData": true
},
"language": "it"
}
-
HTTP 201
{ "success": true, "id": "reservation-id", "href": "public-url-for-reservation", "errors": null }
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
GET /api/v1/admin/event/{slug}/reservation/{reservationId}
-
HTTP 200 see ReservationDetail
{ "id": "abcd", "status": "COMPLETE", "user": { "firstName": "Test", "lastName": "McTest", "email": "[email protected]" }, "tickets": [ { "ticketCategoryId": 53, "quantity": "1", "attendees": [{ "firstName": "Test", "lastName": "McTest", "email": "[email protected]", "metadata": { "attributeForTicket1": "value" }, "additional": { "key": ["value"] }, "resources": { "ticketPdf": "https://instance-address/ticket-url", // only if reservation status is COMPLETE "ticketQrCode": "https://instance-address/ticket-qrcode-image-url", // only if reservation status is COMPLETE "googleWallet": "https://instance-address/google-wallet-url", // only if google wallet support is enabled "applePass": "https://instance-address/apple-pass-url" // only if apple pass support is enabled } }] } ] }
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
GET /api/v1/admin/subscription/{descriptorId}/reservation/{reservationId}
-
HTTP 200 see ReservationDetail
{ "id": "abcd", "status": "COMPLETE", "user": { "firstName": "Test", "lastName": "McTest", "email": "[email protected]" }, "subscriptionOwners": { "firstName": "Test", "lastName": "McTest", "email": "[email protected]", "metadata": { "attributeKey": "value" }, "additional": { "key": ["value"] } } }
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
PUT /api/v1/admin/reservation/{id}/confirm
Sample Body (Reference)
{
"transaction": {
"id": "123456789",
"paymentProvider": "ON_SITE",
"timestamp": "2023-10-22T17:00:00",
"paidAmount": "120.00",
"notes": "test notes"
},
"notification": {
"attendees": true,
"customer": true
}
}
-
HTTP 200
{ "holders": [ { "id": "6ccd858f-d391-4558-9ad0-e39fc9683f49", "firstName": "Test", "lastName": "McTest", "email": "[email protected]" } ] }
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
Removes a ticket from a reservation. After being removed, the ticket will not be valid anymore.
DELETE /api/v1/admin/event/{slug}/reservation/delete-ticket/{UUID}
- HTTP 200 OK
- HTTP 404 Event not found or Ticket not found
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
Cancels a subscription and removes it from a reservation. After being removed, the subscription will not be valid anymore.
DELETE /api/v1/admin/subscription/{descriptorId}/reservation/delete-subscription/{subscriptionId}
- HTTP 200 OK
- HTTP 404 Subscription Descriptor not found or Subscription not found
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/subscription/create
Sample Body (SubscriptionDescriptorModificationRequest)
{
"usageType": "ONCE_PER_EVENT",
"termType": "standard",
"term": {
"timeUnit": "MONTHS",
"units": 1
},
"title": [
{
"lang": "en",
"body": "this is the title"
}
],
"description": [
{
"lang": "en",
"body": "this is the description"
}
],
"onSaleFrom": "2022-07-23T12:00:18.22831",
"onSaleTo": "2022-12-23T12:00:18.22831",
"price": "10.00",
"taxPercentage": "7.7",
"taxPolicy": "INCLUDED",
"currencyCode": "CHF",
"imageUrl": "https://alf.io/img/tutorials/check-in-app/003.png",
"termsAndConditionsUrl": "https://alf.io",
"privacyPolicyUrl": "https://alf.io",
"timezone": "Europe/Zurich",
"supportsTicketsGeneration": false,
"paymentMethods": [
"STRIPE"
],
"isPublic": true
}
- HTTP 200 {ID} - the subscription descriptor auto-generated ID (UUID)
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/subscription/{id}/update
Sample Body (SubscriptionDescriptorModificationRequest)
{
"usageType": "ONCE_PER_EVENT",
"termType": "standard",
"term": {
"timeUnit": "MONTHS",
"units": 1
},
"title": [
{
"lang": "en",
"body": "this is the title"
}
],
"description": [
{
"lang": "en",
"body": "this is the description"
}
],
"onSaleFrom": "2022-07-23T12:00:18.22831",
"onSaleTo": "2022-12-23T12:00:18.22831",
"price": "10.00",
"taxPercentage": "7.7",
"taxPolicy": "INCLUDED",
"currencyCode": "CHF",
"imageUrl": "https://alf.io/img/tutorials/check-in-app/003.png",
"termsAndConditionsUrl": "https://alf.io",
"privacyPolicyUrl": "https://alf.io",
"timezone": "Europe/Zurich",
"supportsTicketsGeneration": false,
"paymentMethods": [
"STRIPE"
],
"isPublic": true
}
- HTTP 200 {ID}
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
GET /api/v1/admin/subscription/{id}
- HTTP 200 SubscriptionDescriptorWithStatistics
- HTTP 404 Not found
- HTTP 500 Error descriptor
Returns events linked with a given Subscription Descriptor
GET /api/v1/admin/subscription/{id}/events
- HTTP 200 Array of LinkedEvent
- HTTP 404 Not found
- HTTP 500 Error descriptor
Updates linked Events for a given Subscription Descriptor
POST /api/v1/admin/subscription/{id}/events
[
{
"slug": "event_1"
},
{
"slug": "event_2",
"categories": [ 1, 2]
}
]
- HTTP 200 Array of LinkedEvent
- HTTP 404 Not found
- HTTP 500 Error descriptor
Deactivates a given Subscription Descriptor. This will prevent people from using purchased subscriptions and from purchasing new ones of the same kind.
DELETE /api/v1/admin/subscription/{id}/deactivate
- HTTP 200 Subscription Descriptor has been deactivated
- HTTP 404 Not found
- HTTP 500 Error descriptor
Name | Description | Mandatory |
---|---|---|
title | The event name | * |
slug | Short name, used in URLs | |
description | Array of i18n, Markdown-formatted descriptions | * |
description.lang | Language code | * |
description.body | Localized, Markdown formatted, text | * |
location | Event Location | * |
location.fullAddress | Location address | * |
location.coordinate | geolocation data: latitude and longitude | * |
timezone | time zone identifier (e.g. Europe/Zurich, see List of tz database time zones) | * |
startDate | start date/time, format: YYYY-MM-DDTHH:mm:SS | * |
endDate | start date/time, format: YYYY-MM-DDTHH:mm:SS | * |
websiteUrl | The URL of the event website (can be a dedicated page, or a generic website) | * |
termsAndConditionsUrl | T&C URL | * |
privacyPolicyUrl | Privacy Policy URL | |
imageUrl | URL for retrieving the Event Logo. Must be accessible from alf.io's server | * |
tickets | ticket categories definition | * |
tickets.freeOfCharge | whether or not the event is free of charge | * |
tickets.max | the maximum allowed seats | * |
tickets.currency | ISO 4217 currency code (e.g. CHF, EUR, USD) | if freeOfCharge is false |
tickets.taxPercentage | VAT/GST percentage | if freeOfCharge is false |
tickets.taxIncludedInPrice | Whether the prices are already VAT/GST inclusive | if freeOfCharge is false |
tickets.paymentMethods | Allowed Payment methods | if freeOfCharge is false |
tickets.categories | Available ticket categories | * |
tickets.categories[n].id | Category ID, as returned by the /stats endpoint. Make sure to specify it on update | |
tickets.categories[n].name | Name | * |
tickets.categories[n].description | i18n Localized descriptions | |
tickets.categories[n].maxTickets | Maximum tickets to allocate for this category | |
tickets.categories[n].accessRestricted | Make the category private and generate unique access codes for it. Requires maxTickets > 0 | |
tickets.categories[n].price | Ticket price for this category | if tickets.freeOfCharge is false |
tickets.categories[n].startSellingDate | Start Selling Date/Time | * |
tickets.categories[n].endSellingDate | End Selling Date/Time | * |
tickets.categories[n].groupLink | Tickets for this category can only be assigned to people in the given Group | |
tickets.categories[n].groupLink.groupId | Group ID | * |
tickets.categories[n].groupLink.type | Link type | * |
tickets.categories[n].groupLink.matchType | Matching type | * |
tickets.categories[n].groupLink.maxAllocation | max tickets allowed per match | if matchType is "LIMITED_QUANTITY" |
extensionSettings | settings for extensions | |
extensionSettings.extensionId | the id as defined in the Repository | * |
extensionSettings.key | extension setting key | * |
extensionSettings.value | extension setting value | * |
Name | Description | Mandatory |
---|---|---|
tickets | Tickets to reserve | * |
tickets.*.ticketCategoryId | Category ID | * |
tickets.*.quantity | number of tickets for the given category ID | * |
tickets.*.attendees | Attendees for this category | |
additionalServices | additional items to reserve | |
additionalServices.*.additionalServiceId | additional service ID | * |
additionalServices.*.quantity | number of additional services items | * |
promoCode | promoCode to apply | |
user | authenticated user who is performing the reservation | |
user.username | username. Depending on the Authentication system in use, can be the user email | * |
user.firstName | First name | * |
user.lastName | Last name | * |
user.email | * | |
user.id | External ID, this attribute is currently ignored | |
subscriptionId | Subscription code to apply | |
configuration | reservation process configuration | |
configuration.hideContactData | whether to hide the "contact data" section. Useful if user was specified | |
configuration.hideConfirmationButtons | hide buttons on confirmation page (buy other tickets, back to organizer). | |
configuration.lockEmailEdit | Do not edit email address for attendee. Only if you provided attendees.*.email |
Name | Description | Mandatory |
---|---|---|
metadata | key/value map of custom properties that will be linked to the generated subscription | |
language | IETF BCP 47 language tag | |
user | authenticated end user who is performing the reservation | |
user.username | username. Depending on the Authentication system in use, can be the user email | * |
user.firstName | First name | * |
user.lastName | Last name | * |
user.email | * | |
user.id | External ID, this attribute is currently ignored | |
configuration | reservation process configuration | |
configuration.hideContactData | whether to hide the "contact data" section. Useful if user was specified | |
subscriptionConfiguration | subscription-specific configurations | |
subscriptionConfiguration.displayPin | display PIN on confirmation page and PDF (default true ) |
Name | Description | Mandatory |
---|---|---|
transaction | Transaction details | * |
transaction.id | Transaction identifier | * |
transaction.paymentProvider | PaymentProvider used. If in doubt, use 'ADMIN' | * |
transaction.timestamp | timestamp of the transaction | * |
transaction.paidAmount | amount paid from attendee | |
transaction.notes | notes | |
notification | notification settings | * |
notification.attendees | notify attendees (ticket/subscription holders) | |
notification.customer | notify customer |
GET /api/v1/admin/system/organization/list
- HTTP 200 Array<Organization>
- HTTP 500 Error descriptor
GET /api/v1/admin/system/organization/{id}
- HTTP 200 Organization
- HTTP 404 Organization ID not found
- HTTP 500 Error descriptor
POST /api/v1/admin/system/organization/create
Sample Body (OrganizationModification)
{
"name": "New Organization",
"email": "[email protected]",
"description": "mandatory description"
}
- HTTP 200 Organization
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
POST /api/v1/admin/system/organization/{id}
Sample Body (OrganizationModification)
{
"id": 1,
"name": "New Name",
"email": "[email protected]",
"description": "mandatory description"
}
- HTTP 200 Organization
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
DELETE /api/v1/admin/system/organization/{id}
Warning This will delete all Events, Subscriptions, Reservations owned by the Organization you're deleting
- HTTP 200 OK
- HTTP 400 Error descriptor
- HTTP 500 Error descriptor
PUT /api/v1/admin/system/organization/{id}/api-key
{
"type": "SUPERVISOR",
"description": "API Key Description"
}
type
must be one of
API_CLIENT
SUPERVISOR
SPONSOR
OPERATOR
-
HTTP 200 OrganizationApiKey
{ "organizationId": 123, "apiKey": "abcd" }
- HTTP 500 Error descriptor
DELETE /api/v1/admin/system/organization/{id}/api-key/{apiKey}
- HTTP 200
- HTTP 500 Error descriptor
We would like to thank
for sponsoring the development of this feature. Thank you!