MENU navbar-image

Introduction

API reference for the Simetric Club platform.

This documentation describes the API endpoints used by Simetric Club.

Authenticated endpoints require a Sanctum bearer token in the Authorization header. Use the Try It Out button to test requests against the configured application URL.

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer Bearer {YOUR_API_TOKEN}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Create an API token from the developer dashboard and send it as a bearer token.

Events

Get an event by its slug.

requires authentication

Example request:
curl --request GET \
    --get "http://localhost:8002/api/posts/summer-festival" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/summer-festival"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": {
        "id": 1,
        "title": "Summer Festival",
        "slug": "summer-festival",
        "content": "<p>Event description</p>",
        "category": {},
        "image": "https://example.com/storage/events/summer-festival.jpg",
        "image_2": null,
        "description": "An outdoor music festival.",
        "ticket_form_color": "#000000",
        "timezone": "America/Bogota",
        "currency": "USD",
        "votes": {
            "user_vote_type": null,
            "likes": 0,
            "dislikes": 0
        },
        "tags": [],
        "seat_map_config": null,
        "occupied_seats": [],
        "assistant_fields": {},
        "questions": []
    },
    "message": "Success",
    "code": 200
}
 

Example response (404):


{
    "message": "No query results for model [App\\Post]."
}
 

Request      

GET api/posts/{post_slug}

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

post_slug   string   

The event slug. Example: summer-festival

List the questions configured for an event.

requires authentication

Example request:
curl --request GET \
    --get "http://localhost:8002/api/posts/summer-festival/questions" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/summer-festival/questions"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "statement": "What is your preferred meal?",
            "description": "Choose one option.",
            "required": true,
            "only_main_assistant": true,
            "type": "radio",
            "options": [
                "Vegetarian",
                "Regular"
            ]
        }
    ]
}
 

Request      

GET api/posts/{post_slug}/questions

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

post_slug   string   

The event slug. Example: summer-festival

List the bank accounts configured for an event.

requires authentication

Example request:
curl --request GET \
    --get "http://localhost:8002/api/posts/summer-festival/bank-accounts" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/summer-festival/bank-accounts"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "type": "bank_account",
            "identification_number": "900123456",
            "name": "Simetric Club",
            "bank": "Example Bank",
            "account_number": "000123456789",
            "account_type": "savings",
            "email": "[email protected]",
            "image": null
        }
    ]
}
 

Request      

GET api/posts/{post_slug}/bank-accounts

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

post_slug   string   

The event slug. Example: summer-festival

Ticket Types

List the ticket types available for an event.

requires authentication

The endpoint is available both as an event-scoped resource and as the global /api/ticket-types route.

Example request:
curl --request GET \
    --get "http://localhost:8002/api/posts/summer-festival/ticket-types?display_disabled=" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/summer-festival/ticket-types"
);

const params = {
    "display_disabled": "0",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "General Admission",
            "is_courtesy": false,
            "is_tax_included": true,
            "payment_methods": {},
            "payment_method_commissions": {},
            "max_availability_date": null,
            "no_require_confirmation": true,
            "min_by_sell": 1,
            "max_by_sell": 10,
            "per_unit": false,
            "description": "Standard entry ticket.",
            "tax_rate": 15,
            "configured_amount": "100.00",
            "amount_base": "100.00",
            "amount_service": "0.00",
            "amount_with_service": "100.00",
            "amount_tax": "15.00",
            "amount_with_tax": "115.00",
            "amount_total": "115.00",
            "amounts_by_payment_method": {},
            "quantity": 100,
            "tickets_count": 0,
            "is_out_stock": false,
            "request_assistant_information": false,
            "all_assistants_same_price": false,
            "assistant_fields": {},
            "questions": [],
            "has_discounts": false,
            "addons": []
        }
    ]
}
 

Request      

GET api/posts/{post_slug}/ticket-types

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

post_slug   string   

The event slug. Example: summer-festival

Query Parameters

display_disabled   boolean  optional  

Include disabled ticket types. Defaults to false. Example: false

Apply a discount code to a ticket type and return its calculated price.

Example request:
curl --request POST \
    "http://localhost:8002/api/ticket-types/discount" \
    --header "Content-Type: application/json" \
    --data "{
    \"ticket_type_id\": 1,
    \"discount_code\": \"EARLYBIRD\"
}"
const url = new URL(
    "http://localhost:8002/api/ticket-types/discount"
);

const headers = {
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "ticket_type_id": 1,
    "discount_code": "EARLYBIRD"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "data": {
        "id": 1,
        "name": "General Admission",
        "configured_amount": "100.00",
        "amount_total": "90.00",
        "has_discounts": true
    },
    "applied_discount": {
        "code": "EARLYBIRD",
        "discount": 10,
        "discount_unit": "percentage"
    }
}
 

Example response (422):


{
    "message": "The selected ticket_type_id is invalid."
}
 

Request      

POST api/ticket-types/discount

Headers

Content-Type      

Example: application/json

Body Parameters

ticket_type_id   integer   

The ticket type ID. Example: 1

discount_code   string   

The discount code to apply. Example: EARLYBIRD

Generate a JPEG preview image of a ticket configuration.

Configuration values are applied to temporary models and are not saved. The response body is a binary image with Content-Type: image/jpeg.

Example request:
curl --request POST \
    "http://localhost:8002/api/ticket-types/preview" \
    --header "Content-Type: multipart/form-data" \
    --form "post_id=1"\
    --form "ticket_type_id=1"\
    --form "invitation_template_active=1"\
    --form "invitation_template_qr_inactive=1"\
    --form "invitation_template_url=http://bahringer.com/est-omnis-consectetur-iste-est-nostrum-doloribus-aut"\
    --form "margin_top=170.327"\
    --form "margin_bottom=274.84"\
    --form "font_size=5045.382945"\
    --form "title_offset=9.9"\
    --form "font_color=#000000"\
    --form "invitation_template_image=@/tmp/phpscwD5N" \
    --form "invitation_font_file=@/tmp/php899YuE" 
const url = new URL(
    "http://localhost:8002/api/ticket-types/preview"
);

const headers = {
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('post_id', '1');
body.append('ticket_type_id', '1');
body.append('invitation_template_active', '1');
body.append('invitation_template_qr_inactive', '1');
body.append('invitation_template_url', 'http://bahringer.com/est-omnis-consectetur-iste-est-nostrum-doloribus-aut');
body.append('margin_top', '170.327');
body.append('margin_bottom', '274.84');
body.append('font_size', '5045.382945');
body.append('title_offset', '9.9');
body.append('font_color', '#000000');
body.append('invitation_template_image', document.querySelector('input[name="invitation_template_image"]').files[0]);
body.append('invitation_font_file', document.querySelector('input[name="invitation_font_file"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (200):


{
    "content_type": "image/jpeg"
}
 

Request      

POST api/ticket-types/preview

Headers

Content-Type      

Example: multipart/form-data

Body Parameters

post_id   integer  optional  

The existing post ID used as the preview base. Example: 1

ticket_type_id   integer  optional  

The existing ticket type ID used as the preview base. Example: 1

invitation_template_active   boolean  optional  

Enable the invitation template. Defaults to true. Example: true

invitation_template_qr_inactive   boolean  optional  

Hide the QR code. Defaults to false. Example: true

invitation_template_url   string  optional  

The invitation template URL. Example: http://bahringer.com/est-omnis-consectetur-iste-est-nostrum-doloribus-aut

margin_top   number  optional  

The top margin. Example: 170.327

margin_bottom   number  optional  

The bottom margin. Example: 274.84

font_size   number  optional  

The invitation font size. Example: 5045.382945

title_offset   number  optional  

The title vertical offset. Example: 9.9

font_color   string  optional  

The invitation font color. Example: #000000

invitation_template_image   file  optional  

The invitation template image. Example: /tmp/phpscwD5N

invitation_font_file   file  optional  

The custom invitation font. Example: /tmp/php899YuE

List the ticket types available for an event.

The endpoint is available both as an event-scoped resource and as the global /api/ticket-types route.

Example request:
curl --request GET \
    --get "http://localhost:8002/api/ticket-types?display_disabled=1"
const url = new URL(
    "http://localhost:8002/api/ticket-types"
);

const params = {
    "display_disabled": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

fetch(url, {
    method: "GET",
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "name": "General Admission",
            "is_courtesy": false,
            "is_tax_included": true,
            "payment_methods": {},
            "payment_method_commissions": {},
            "max_availability_date": null,
            "no_require_confirmation": true,
            "min_by_sell": 1,
            "max_by_sell": 10,
            "per_unit": false,
            "description": "Standard entry ticket.",
            "tax_rate": 15,
            "configured_amount": "100.00",
            "amount_base": "100.00",
            "amount_service": "0.00",
            "amount_with_service": "100.00",
            "amount_tax": "15.00",
            "amount_with_tax": "115.00",
            "amount_total": "115.00",
            "amounts_by_payment_method": {},
            "quantity": 100,
            "tickets_count": 0,
            "is_out_stock": false,
            "request_assistant_information": false,
            "all_assistants_same_price": false,
            "assistant_fields": {},
            "questions": [],
            "has_discounts": false,
            "addons": []
        }
    ]
}
 

Request      

GET api/ticket-types

Query Parameters

display_disabled   boolean  optional  

Include disabled ticket types. Defaults to false. Example: true

Vouchers

Register a ticket purchase intention for an event.

requires authentication

Example request:
curl --request POST \
    "http://localhost:8002/api/posts/summer-festival/tickets" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: multipart/form-data" \
    --form "assistant[payment_method]=voucher"\
    --form "assistant[skip_otp]="\
    --form "adds_accepted=1"\
    --form "require_tax=1"\
    --form "tickets[][is_main]=1"\
    --form "tickets[][ticket_type_id]=1"\
    --form "tickets[][quantity]=1"\
    --form "tickets[][discount_code]=EARLYBIRD"\
    --form "tickets[][name]=Jane Doe"\
    --form "tickets[][email][email protected]"\
    --form "tickets[][phone]=+593999999999"\
    --form "tickets[][identification_number]=0912345678"\
    --form "tickets[][answers][1]=Vegetarian"\
    --form "tickets[][answers][2]=No"\
    --form "tickets[][seats][][ticket_type_id]=1"\
    --form "tickets[][seats][][coordinate]=A-01"\
    --form "tickets[][seats][][label]=A1"\
    --form "tickets[][addons][][ticket_type_id]=1"\
    --form "tickets[][addons][][id]=1"\
    --form "tickets[][addons][][quantity]=1"\
    --form "invoice_data[name]=Jane Doe"\
    --form "invoice_data[identification_type]=05"\
    --form "invoice_data[identification_number]=0999999999001"\
    --form "invoice_data[address]=123 Main Street"\
    --form "invoice_data[email][email protected]"\
    --form "invoice_data[phone]=+593999999999"\
    --form "assistant[voucher]=@/tmp/phpi4cpkp4viv5b2tokR0E" 
const url = new URL(
    "http://localhost:8002/api/posts/summer-festival/tickets"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Content-Type": "multipart/form-data",
    "Accept": "application/json",
};

const body = new FormData();
body.append('assistant[payment_method]', 'voucher');
body.append('assistant[skip_otp]', '');
body.append('adds_accepted', '1');
body.append('require_tax', '1');
body.append('tickets[][is_main]', '1');
body.append('tickets[][ticket_type_id]', '1');
body.append('tickets[][quantity]', '1');
body.append('tickets[][discount_code]', 'EARLYBIRD');
body.append('tickets[][name]', 'Jane Doe');
body.append('tickets[][email]', '[email protected]');
body.append('tickets[][phone]', '+593999999999');
body.append('tickets[][identification_number]', '0912345678');
body.append('tickets[][answers][1]', 'Vegetarian');
body.append('tickets[][answers][2]', 'No');
body.append('tickets[][seats][][ticket_type_id]', '1');
body.append('tickets[][seats][][coordinate]', 'A-01');
body.append('tickets[][seats][][label]', 'A1');
body.append('tickets[][addons][][ticket_type_id]', '1');
body.append('tickets[][addons][][id]', '1');
body.append('tickets[][addons][][quantity]', '1');
body.append('invoice_data[name]', 'Jane Doe');
body.append('invoice_data[identification_type]', '05');
body.append('invoice_data[identification_number]', '0999999999001');
body.append('invoice_data[address]', '123 Main Street');
body.append('invoice_data[email]', '[email protected]');
body.append('invoice_data[phone]', '+593999999999');
body.append('assistant[voucher]', document.querySelector('input[name="assistant[voucher]"]').files[0]);

fetch(url, {
    method: "POST",
    headers,
    body,
}).then(response => response.json());

Example response (201):


{
    "message": "Ticket created successfully",
    "data": {
        "order_hash": "65f1c9a7",
        "currency": "USD",
        "tickets_data": [
            {
                "hash": "4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e",
                "amount": 100,
                "amount_with_tax": 115,
                "amount_tax": 15,
                "amount_payment_gateway": 0,
                "tax": 15,
                "discounts": [],
                "ticket_type": {
                    "id": 1,
                    "name": "General Admission"
                },
                "assistant": {
                    "id": 1,
                    "name": "Jane Doe",
                    "email": "[email protected]"
                },
                "is_main": true,
                "seat_coordinate": null,
                "seat_label": null
            }
        ]
    }
}
 

Example response (422):


{
    "message": "Aforo máximo alcanzado para la localidad General Admission. Por favor, elige otra localidad o reduce la cantidad de tickets."
}
 

Request      

POST api/posts/{post_slug}/tickets

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

Content-Type      

Example: multipart/form-data

URL Parameters

post_slug   string   

The event slug. Example: summer-festival

Body Parameters

assistant   object   

Payment method and voucher information. Example payload: payment_method=voucher

payment_method   string  optional  

Payment method. Example: voucher

skip_otp   boolean  optional  

Skip OTP generation. Example: false

voucher   file  optional  

Required when the payment method is voucher. JPEG, PNG, or JPG proof of payment. Example: /tmp/phpi4cpkp4viv5b2tokR0E

adds_accepted   boolean  optional  

Whether addons or additional terms were accepted. Example: true

require_tax   boolean  optional  

Whether tax is required. Example: true

tickets   object[]   

Ticket selections and attendee information.

is_main   boolean  optional  

Whether this attendee is the main assistant. Example: true

ticket_type_id   integer  optional  

Ticket type ID. Example: 1

quantity   integer  optional  

Quantity for this ticket type. Example: 1

discount_code   string  optional  

Discount code for this ticket type. Example: EARLYBIRD

name   string   

Attendee name. Example: Jane Doe

email   string   

Attendee email. Example: [email protected]

phone   string   

Attendee phone number. Example: +593999999999

identification_number   string   

Attendee identification number. Example: 0912345678

answers   object  optional  

Answers keyed by question ID.

seats   object[]  optional  

Selected seats.

ticket_type_id   integer  optional  

Ticket type ID for the selected seat. Example: 1

coordinate   string   

Seat coordinate. Example: A-01

label   string   

Seat label. Example: A1

addons   object[]  optional  

Addons selected for the ticket type.

ticket_type_id   integer  optional  

Ticket type ID for the addon. Example: 1

id   integer  optional  

Addon ID. Example: 1

quantity   integer  optional  

Addon quantity. Example: 1

invoice_data   object  optional  

Invoice information. Example payload: name=Jane Doe, identification_number=0999999999001, [email protected]

name   string  optional  

Invoice recipient name. Example: Jane Doe

identification_type   string  optional  

Invoice recipient identification type. Example: 05

identification_number   string  optional  

Invoice recipient identification number. Example: 0999999999001

address   string  optional  

Invoice recipient address. Example: 123 Main Street

email   string  optional  

Invoice recipient email. Example: [email protected]

phone   string  optional  

Invoice recipient phone number. Example: +593999999999

Send the voucher invitations by email.

requires authentication

Example request:
curl --request PUT \
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/send-mail" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/send-mail"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "Mail sent successfully"
}
 

Example response (500):


{
    "message": "An error occurred while sending the mail."
}
 

Request      

PUT api/posts/vouchers/{voucher_hash}/send-mail

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

voucher_hash   string   

The voucher hash. Example: 4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e

Validate the OTP associated with a voucher.

requires authentication

Example request:
curl --request PUT \
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/otp-validate" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}" \
    --header "Content-Type: application/json" \
    --data "{
    \"otp\": \"123456\"
}"
const url = new URL(
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/otp-validate"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "otp": "123456"
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Example response (200):


{
    "message": "OTP validated successfully",
    "data": {
        "order_hash": "4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e",
        "currency": "USD",
        "event_name": "Summer Festival",
        "payment_data": {
            "method": "voucher"
        },
        "tickets_data": [],
        "addons": []
    }
}
 

Example response (400):


{
    "message": "The OTP entered is invalid."
}
 

Request      

PUT api/posts/vouchers/{voucher_hash}/otp-validate

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

Content-Type      

Example: application/json

URL Parameters

voucher_hash   string   

The voucher hash. Example: 4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e

Body Parameters

otp   string   

The six-digit OTP. Example: 123456

Resend the OTP associated with a voucher.

requires authentication

Example request:
curl --request PUT \
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/retry-otp" \
    --header "Authorization: Bearer Bearer {YOUR_API_TOKEN}"
const url = new URL(
    "http://localhost:8002/api/posts/vouchers/4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e/retry-otp"
);

const headers = {
    "Authorization": "Bearer Bearer {YOUR_API_TOKEN}",
    "Accept": "application/json",
};

fetch(url, {
    method: "PUT",
    headers,
}).then(response => response.json());

Example response (200):


{
    "message": "OTP resent successfully"
}
 

Request      

PUT api/posts/vouchers/{voucher_hash}/retry-otp

Headers

Authorization      

Example: Bearer Bearer {YOUR_API_TOKEN}

URL Parameters

voucher_hash   string   

The voucher hash. Example: 4f2c8f2a6b8f4a3d9c8e7f6a5b4c3d2e