API

Документація API

Усе для підключення сайту, мобільного застосунку та AI-помічників до Ladna.

OpenAPI JSON

Підключення з перевіркою доступу

Входи до мобільного застосунку, дії від імені студії та службові повідомлення від платіжних сервісів.

get Mobile studio

Returns public studio metadata and customer authentication methods for the native mobile app.

/api/v1/mobile/studios/{accountSlug}

post Mobile auth

Authenticates a studio owner or staff member and returns one mobile session token per accessible studio account.

/api/v1/mobile/auth/staff/login

post Mobile auth

Authenticates or creates a studio customer with email and password, then returns a mobile customer session.

/api/v1/mobile/auth/customer/email-login

post Mobile auth

Sends an OTP challenge for customer phone login when the studio customer auth settings allow OTP.

/api/v1/mobile/auth/customer/otp/send

post Mobile auth

Verifies a customer OTP challenge and returns a mobile customer session.

/api/v1/mobile/auth/customer/otp/verify

get Mobile auth

Starts Google OAuth for a customer and redirects to Google.

/api/v1/mobile/auth/customer/google/{accountSlug}/redirect

get Mobile auth

Receives the Google OAuth callback and redirects to the mobile return URL with a one-time exchange code.

/api/v1/mobile/auth/customer/google/callback

post Mobile auth

Exchanges a one-time Google mobile login code for a customer mobile session.

/api/v1/mobile/auth/customer/google/exchange

get Mobile auth

Returns the current mobile session profile, account, actor, and permissions.

/api/v1/mobile/me

post Mobile auth

Revokes the current mobile session token.

/api/v1/mobile/logout

post Mobile auth

Registers or updates a mobile push notification token for the current mobile session.

/api/v1/mobile/device-tokens

get Mobile schedule

Returns account-scoped scheduled classes for the mobile actor. Customer sessions see public group classes only; trainer sessions are narrowed to the linked trainer.

/api/v1/mobile/schedule

get Mobile schedule

Returns one account-scoped scheduled class for the mobile actor.

/api/v1/mobile/classes/{scheduledClass}

post Mobile bookings

Books the current customer into a public group class.

/api/v1/mobile/classes/{scheduledClass}/customer-booking

post Mobile bookings

Creates or reactivates a booking for a selected customer. Requires the manage_bookings studio permission.

/api/v1/mobile/classes/{scheduledClass}/staff-bookings

patch Mobile bookings

Updates booking status from a staff session. Setting cancelled before the cutoff releases the class-pass session and keeps the booking in history.

/api/v1/mobile/bookings/{classBooking}

delete Mobile bookings

Cancels a booking before the cutoff and releases the class-pass session while keeping the booking in history. Staff need manage_bookings.

/api/v1/mobile/bookings/{classBooking}

get Mobile customer

Returns the current customer booking history for the session account.

/api/v1/mobile/customer/bookings

get Mobile customer

Returns the current customer class passes for the session account.

/api/v1/mobile/customer/passes

put Mobile customer

Updates the current customer profile for the session account. If the phone belongs to another customer in this studio, returns a validation response with code phone_verification_required.

/api/v1/mobile/customer/profile

post Mobile customer

Sends an OTP challenge to confirm a duplicate profile phone before merging customer identities.

/api/v1/mobile/customer/profile/phone/send

post Mobile customer

Resends an OTP challenge for the pending duplicate profile phone confirmation.

/api/v1/mobile/customer/profile/phone/resend

post Mobile customer

Verifies a duplicate profile phone OTP, merges the temporary email or Google identity into the existing phone customer, and returns the refreshed customer session.

/api/v1/mobile/customer/profile/phone/verify

get Mobile customer

Searches account customers for staff booking flows. Requires manage_bookings or manage_clients.

/api/v1/mobile/staff/customers

post Website leads

Creates a website lead for the studio identified by the bearer token with the website_leads:create ability.

/api/v1/website-leads

post Festival payments

Receives a payment provider callback for a Festival performance charge or spectator admission order.

/api/v1/festival-payments/{provider}/callbacks

get Festival battles

Lists ready knockout matches from published or in-progress Festival editions.

/api/v1/festival-battles/matches

get Festival battles

Returns the current aggregate state of one ready or completed Festival battle.

/api/v1/festival-battles/matches/{match}

put Festival battles

Idempotently records the normalized applause score and finalizes when all four judge votes permit it.

/api/v1/festival-battles/matches/{match}/audience-score

Авторизація

Для частини запитів потрібен вхід у мобільний застосунок, а для дій від імені студії — окремий ключ із Налаштувань акаунта → Інтеграції → API-ключі.

Authorization: Bearer ladna_your_token

Заявка з сайту

POST /api/v1/website-leads

PHP
$response = (new \GuzzleHttp\Client())->request('POST', 'https://ladna.app/api/v1/website-leads', [
    'headers' => [
        'Authorization' => 'Bearer ladna_your_token',
        'Accept' => 'application/json',
    ],
    'json' => json_decode('{
    "phone": "+380671112233",
    "name": "Олена Коваль",
    "source_page": "https://studio.example.com/trial"
}', true),
]);

$data = json_decode((string) $response->getBody(), true);
Python
import requests

response = requests.request(
    'POST',
    'https://ladna.app/api/v1/website-leads',
    headers={
        'Authorization': 'Bearer ladna_your_token',
        'Accept': 'application/json',
    },
    json={
    "phone": "+380671112233",
    "name": "Олена Коваль",
    "source_page": "https://studio.example.com/trial"
},
)
response.raise_for_status()
data = response.json()
JS
const response = await fetch('https://ladna.app/api/v1/website-leads', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ladna_your_token',
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "phone": "+380671112233",
    "name": "Олена Коваль",
    "source_page": "https://studio.example.com/trial"
}),
});

const data = await response.json();

Готові батли фестивалю

GET /api/v1/festival-battles/matches

PHP
$response = (new \GuzzleHttp\Client())->request('GET', 'https://ladna.app/api/v1/festival-battles/matches', [
    'headers' => [
        'Authorization' => 'Bearer ladna_your_token',
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true);
Python
import requests

response = requests.request(
    'GET',
    'https://ladna.app/api/v1/festival-battles/matches',
    headers={
        'Authorization': 'Bearer ladna_your_token',
        'Accept': 'application/json',
    },
)
response.raise_for_status()
data = response.json()
JS
const response = await fetch('https://ladna.app/api/v1/festival-battles/matches', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ladna_your_token',
    'Accept': 'application/json',
  },
});

const data = await response.json();

Надсилання оцінки оплесків глядачів

PUT /api/v1/festival-battles/matches/{match}/audience-score

PHP
$response = (new \GuzzleHttp\Client())->request('PUT', 'https://ladna.app/api/v1/festival-battles/matches/42/audience-score', [
    'headers' => [
        'Authorization' => 'Bearer ladna_your_token',
        'Accept' => 'application/json',
    ],
    'json' => json_decode('{
    "audience_score_a": 612345,
    "audience_score_b": 387655,
    "measurement": {
        "metric": "baseline_adjusted_integrated_energy",
        "baseline_duration_ms": 2000,
        "duration_ms": 5000,
        "baseline_dbfs": -52.4,
        "mean_dbfs_a": -18.2,
        "mean_dbfs_b": -20.1,
        "peak_dbfs_a": -2.1,
        "peak_dbfs_b": -3.4
    }
}', true),
]);

$data = json_decode((string) $response->getBody(), true);
Python
import requests

response = requests.request(
    'PUT',
    'https://ladna.app/api/v1/festival-battles/matches/42/audience-score',
    headers={
        'Authorization': 'Bearer ladna_your_token',
        'Accept': 'application/json',
    },
    json={
    "audience_score_a": 612345,
    "audience_score_b": 387655,
    "measurement": {
        "metric": "baseline_adjusted_integrated_energy",
        "baseline_duration_ms": 2000,
        "duration_ms": 5000,
        "baseline_dbfs": -52.4,
        "mean_dbfs_a": -18.2,
        "mean_dbfs_b": -20.1,
        "peak_dbfs_a": -2.1,
        "peak_dbfs_b": -3.4
    }
},
)
response.raise_for_status()
data = response.json()
JS
const response = await fetch('https://ladna.app/api/v1/festival-battles/matches/42/audience-score', {
  method: 'PUT',
  headers: {
    'Authorization': 'Bearer ladna_your_token',
    'Accept': 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "audience_score_a": 612345,
    "audience_score_b": 387655,
    "measurement": {
        "metric": "baseline_adjusted_integrated_energy",
        "baseline_duration_ms": 2000,
        "duration_ms": 5000,
        "baseline_dbfs": -52.4,
        "mean_dbfs_a": -18.2,
        "mean_dbfs_b": -20.1,
        "peak_dbfs_a": -2.1,
        "peak_dbfs_b": -3.4
    }
}),
});

const data = await response.json();