Introduction
API documentation for the VetLlama white-label SaaS backend.
VetLlama is a white-label API backend for tenant-owned service booking businesses. The current API foundation covers platform administration, public tenant owner signup, tenant owner authentication, tenant/domain resolution, public tenant configuration, and limited end-user magic-link authentication.
All requests should send `Accept: application/json`. Authenticated routes use JWT Bearer tokens in the `Authorization` header.
Tenant-scoped public and end-user flows resolve tenant context from the request host. In local development, use a host such as `demo.vetllama.test` when calling `/api/public/*` and `/api/user/*` tenant-scoped endpoints.
The documentation is organized around three actor surfaces: Admin, Tenant, and User.
Development seed credentials, when shown, are for local environments only and must not be used in production.
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Use the JWT returned by the relevant login flow: Admin, TenantOwner, or EndUser magic-link verification. Tokens are scoped by guard; an Admin token cannot access TenantOwner or EndUser routes.
Admin
Auth
Login
Authenticates a platform admin and returns an Admin-scoped JWT. Development seed example only: admin@vetllama.test / LocalDevPassword123!.
Example request:
curl --request POST \
"https://api.vetllama.com/api/admin/auth/login" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"admin@vetllama.test\",
\"password\": \"LocalDevPassword123!\",
\"device_token\": \"web-admin-device\"
}"
const url = new URL(
"https://api.vetllama.com/api/admin/auth/login"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "admin@vetllama.test",
"password": "LocalDevPassword123!",
"device_token": "web-admin-device"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged in successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "admin",
"expires_in": 3600,
"user": {
"id": 1,
"name": "VetLlama Dev Admin",
"email": "admin@vetllama.test",
"is_active": true,
"email_verified_at": "2026-05-17T00:00:00.000000Z"
}
}
}
Example response (422):
{
"success": false,
"message": "The given data was invalid.",
"errors": {
"email": [
"Invalid email or password."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logout
requires authentication
Invalidates the current Admin JWT and closes the latest open auth activity session.
Example request:
curl --request POST \
"https://api.vetllama.com/api/admin/auth/logout" \
--header "Authorization: Bearer {ADMIN_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/admin/auth/logout"
);
const headers = {
"Authorization": "Bearer {ADMIN_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged out successfully.",
"data": null
}
Example response (401):
{
"success": false,
"message": "Unauthenticated."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Refresh Token
requires authentication
Exchanges a valid Admin JWT for a fresh Admin JWT.
Example request:
curl --request POST \
"https://api.vetllama.com/api/admin/auth/refresh" \
--header "Authorization: Bearer {ADMIN_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/admin/auth/refresh"
);
const headers = {
"Authorization": "Bearer {ADMIN_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Token refreshed successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "admin",
"expires_in": 3600,
"user": {
"id": 1,
"name": "VetLlama Dev Admin",
"email": "admin@vetllama.test",
"is_active": true
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Current Profile
requires authentication
Returns the profile for the authenticated platform admin.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/admin/auth/me" \
--header "Authorization: Bearer {ADMIN_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/admin/auth/me"
);
const headers = {
"Authorization": "Bearer {ADMIN_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Profile fetched successfully.",
"data": {
"id": 1,
"name": "VetLlama Dev Admin",
"email": "admin@vetllama.test",
"is_active": true,
"email_verified_at": "2026-05-17T00:00:00.000000Z"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Platform / System
Health Check
Confirms that the VetLlama API process is reachable.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/health" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/health"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "VetLlama API is available."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Tenant
Public Auth
Register Tenant Owner
Creates a draft tenant together with its primary tenant owner, initializes onboarding defaults, creates a primary subdomain host mapping, and returns a JWT so onboarding can start immediately. If desired_subdomain is omitted, the backend generates a unique subdomain from display_name.
Example request:
curl --request POST \
"https://api.vetllama.com/api/public/tenant/auth/register" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"owner_name\": \"Dr. Sarah Khan\",
\"display_name\": \"Paws & Care\",
\"business_name\": \"Paws & Care LLC\",
\"email\": \"owner@demo.vetllama.test\",
\"password\": \"LocalDevPassword123!\",
\"accepted_terms\": true,
\"phone\": \"+10000000000\",
\"desired_subdomain\": \"paws-care\",
\"password_confirmation\": \"LocalDevPassword123!\"
}"
const url = new URL(
"https://api.vetllama.com/api/public/tenant/auth/register"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"owner_name": "Dr. Sarah Khan",
"display_name": "Paws & Care",
"business_name": "Paws & Care LLC",
"email": "owner@demo.vetllama.test",
"password": "LocalDevPassword123!",
"accepted_terms": true,
"phone": "+10000000000",
"desired_subdomain": "paws-care",
"password_confirmation": "LocalDevPassword123!"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (201):
{
"success": true,
"message": "Account created successfully. Onboarding started.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "tenant_owner",
"expires_in": 3600,
"user": {
"id": 1,
"tenant_id": 1,
"name": "Dr. Sarah Khan",
"email": "owner@paws-care.test",
"phone": "+10000000000",
"is_primary": true,
"is_active": true,
"tenant": {
"id": 1,
"name": "Paws & Care",
"slug": "paws-care",
"status": "draft",
"onboarding_status": "in_progress",
"is_active": true
}
}
}
}
Example response (422):
{
"success": false,
"message": "The given data was invalid.",
"errors": {
"email": [
"The email has already been taken."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Public Resolution
Resolve Tenant By Host
Resolves the active tenant from a mapped website host and returns the public configuration needed by the Angular frontend. By default, resolution uses the request Host header. For testing or frontend bootstrapping, you may also pass one explicit query input: host, domain, or subdomain.
Custom domains must be active and verified before they resolve publicly. Managed subdomains resolve immediately once active.
Subdomain examples resolve against VETLLAMA_TENANT_BASE_DOMAIN, such as paws-care.vetllama.test locally. Custom domain examples use the full mapped host, such as paws-care.com.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/resolve?host=paws-care.vetllama.test&domain=paws-care.com&subdomain=paws-care" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/resolve"
);
const params = {
"host": "paws-care.vetllama.test",
"domain": "paws-care.com",
"subdomain": "paws-care",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Tenant configuration resolved.",
"data": {
"tenant": {
"id": 1,
"name": "Demo Clinic",
"slug": "demo-clinic",
"status": "active",
"is_active": true
},
"template": {
"id": 1,
"name": "Classic Practice",
"slug": "classic-practice",
"description": "Local development template for Classic Practice.",
"preview_url": "https://example.com/templates/classic-practice",
"is_active": true,
"schema": {
"sections": [
"hero",
"about",
"banners",
"services",
"faq",
"contact"
],
"required_fields": [
"homepage_content.hero_title",
"homepage_content.hero_subtitle",
"contact_details.email"
]
}
},
"branding": {
"primary_color": "#2563eb",
"secondary_color": "#14b8a6",
"logo_url": "https://example.com/demo/logo.png",
"favicon_url": "https://example.com/demo/favicon.ico",
"social_links": {
"facebook": "https://facebook.com/demo",
"instagram": "https://instagram.com/demo"
}
},
"public_config": {
"contact_details": {
"email": "hello@demo.vetllama.test",
"phone": "+10000000000",
"address": "123 Demo Street"
},
"homepage_content": {
"hero_title": "Care, scheduling, and client access in one place",
"hero_subtitle": "A local-development tenant used to test public config."
},
"banners": [],
"faq": [],
"services": [],
"settings": {
"booking_enabled": false,
"telehealth_enabled": false
},
"is_published": true
}
}
}
Example response (404):
{
"success": false,
"message": "Tenant could not be resolved for this host."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List Public Services
Returns all enabled tenant service offerings with their active duration and pricing options. Tenant is resolved from the Host header or explicit resolver query parameters.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/services?host=pawscare.vetllama.test&domain=pawscare.test&subdomain=pawscare" \
--header "Host: pawscare.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/services"
);
const params = {
"host": "pawscare.vetllama.test",
"domain": "pawscare.test",
"subdomain": "pawscare",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Host": "pawscare.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Services fetched successfully.",
"data": [
{
"id": 1,
"type": "telehealth",
"name": "Telehealth Follow-up",
"description": "Video consultation for follow-ups.",
"delivery_mode": "video",
"duration_options": [
{
"id": 1,
"service_offering_id": 1,
"duration_minutes": 30,
"price": "69.00",
"currency": "USD",
"is_default": true,
"is_active": true
}
]
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Public Service Detail
Returns one enabled public service with active duration and pricing options.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/services/16" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/services/16"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
List Public Locations
Returns active public locations for physical visit preparation.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/locations" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/locations"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Public Policies
Returns public booking policy, FAQ, terms, privacy, and contact blocks.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/policies" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/policies"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Preview Bookable Slots
Generates available bookable slot previews for an active published tenant service. This does not create or reserve a booking.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/slots?service_id=1&duration_id=1&date=2026-05-21&location_id=1" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/slots"
);
const params = {
"service_id": "1",
"duration_id": "1",
"date": "2026-05-21",
"location_id": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Public Tenant Details
Returns the full public tenant website/bootstrap payload, including tenant profile, template, branding, public content, active host mappings, active locations, enabled services, and active duration/pricing options.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/public/tenant/details?host=pawscare.vetllama.test&domain=pawscare.test&subdomain=pawscare" \
--header "Host: pawscare.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/public/tenant/details"
);
const params = {
"host": "pawscare.vetllama.test",
"domain": "pawscare.test",
"subdomain": "pawscare",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Host": "pawscare.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Tenant details fetched successfully.",
"data": {
"tenant": {
"id": 1,
"name": "Paws & Care Veterinary Clinic",
"slug": "paws-care-vet",
"status": "active",
"is_active": true
},
"template": {},
"branding": {},
"public_config": {},
"domains": [],
"locations": [],
"services": []
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Auth
Login
Authenticates a tenant owner/operator and returns a TenantOwner-scoped JWT. Development seed example only: owner@demo.vetllama.test / LocalDevPassword123!.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/auth/login" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"owner@demo.vetllama.test\",
\"password\": \"LocalDevPassword123!\",
\"device_token\": \"web-owner-device\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/auth/login"
);
const headers = {
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "owner@demo.vetllama.test",
"password": "LocalDevPassword123!",
"device_token": "web-owner-device"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged in successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "tenant_owner",
"expires_in": 3600,
"user": {
"id": 1,
"tenant_id": 1,
"name": "Demo Tenant Owner",
"email": "owner@demo.vetllama.test",
"phone": "+10000000000",
"is_primary": true,
"is_active": true,
"tenant": {
"id": 1,
"name": "Demo Clinic",
"slug": "demo-clinic",
"status": "active",
"is_active": true
}
}
}
}
Example response (422):
{
"success": false,
"message": "The given data was invalid.",
"errors": {
"email": [
"Invalid email or password."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logout
requires authentication
Invalidates the current TenantOwner JWT and closes the latest open auth activity session.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/auth/logout" \
--header "Authorization: Bearer {TENANT_OWNER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/auth/logout"
);
const headers = {
"Authorization": "Bearer {TENANT_OWNER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged out successfully.",
"data": null
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Refresh Token
requires authentication
Exchanges a valid TenantOwner JWT for a fresh TenantOwner JWT.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/auth/refresh" \
--header "Authorization: Bearer {TENANT_OWNER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/auth/refresh"
);
const headers = {
"Authorization": "Bearer {TENANT_OWNER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Token refreshed successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "tenant_owner",
"expires_in": 3600,
"user": {
"id": 1,
"tenant_id": 1,
"email": "owner@demo.vetllama.test"
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Current Profile
requires authentication
Returns the authenticated tenant owner and their tenant summary.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/auth/me" \
--header "Authorization: Bearer {TENANT_OWNER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/auth/me"
);
const headers = {
"Authorization": "Bearer {TENANT_OWNER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Profile fetched successfully.",
"data": {
"id": 1,
"tenant_id": 1,
"name": "Demo Tenant Owner",
"email": "owner@demo.vetllama.test",
"phone": "+10000000000",
"is_primary": true,
"is_active": true,
"tenant": {
"id": 1,
"name": "Demo Clinic",
"slug": "demo-clinic",
"status": "active",
"is_active": true
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Templates
List Templates
requires authentication
Lists active website templates available for the tenant owner to select.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/templates" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/templates"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Template Details
requires authentication
Returns the selected template definition, including the schema used by the owner setup UI.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/templates/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/templates/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Select Template
requires authentication
Assigns one active template to the authenticated tenant.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/templates/selection" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"template_id\": \"architecto\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/templates/selection"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"template_id": "architecto"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Profile
Get Tenant Profile
requires authentication
Returns the authenticated tenant's basic profile and onboarding status fields.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/profile" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/profile"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Tenant Profile
requires authentication
Updates owner-facing business profile fields such as display name, slug, contact details, and onboarding status.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/profile" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"business_name\": \"n\",
\"slug\": \"g\",
\"email\": \"rowan.gulgowski@example.com\",
\"primary_phone\": \"d\",
\"secondary_phone\": \"l\",
\"short_bio\": \"architecto\",
\"support_email\": \"zbailey@example.net\",
\"support_phone\": \"i\",
\"status\": \"pending\",
\"onboarding_status\": \"in_progress\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/profile"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"business_name": "n",
"slug": "g",
"email": "rowan.gulgowski@example.com",
"primary_phone": "d",
"secondary_phone": "l",
"short_bio": "architecto",
"support_email": "zbailey@example.net",
"support_phone": "i",
"status": "pending",
"onboarding_status": "in_progress"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Branding
Get Branding
requires authentication
Returns tenant branding assets and colors used by the public website.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/branding" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/branding"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Branding
requires authentication
Updates tenant colors, social links, and branding media. Send multipart/form-data with logo, favicon, profile_photo, or banner_files to store assets on the configured filesystem disk, typically S3.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/branding" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "primary_color=#2563eb"\
--form "secondary_color=#14b8a6"\
--form "logo_url=http://www.bailey.biz/quos-velit-et-fugiat-sunt-nihil-accusantium-harum.html"\
--form "favicon_url=https://www.runte.com/ab-provident-perspiciatis-quo-omnis-nostrum-aut-adipisci"\
--form "profile_photo_url=https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html"\
--form "social_links[instagram]=https://instagram.com/pawscare"\
--form "logo=@/tmp/phpiKtxKX" \
--form "favicon=@/tmp/phpegnmH9" \
--form "profile_photo=@/tmp/phpg8nALD" \
--form "banner_files[]=@/tmp/phpO2Kezd" const url = new URL(
"https://api.vetllama.com/api/tenant/branding"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('primary_color', '#2563eb');
body.append('secondary_color', '#14b8a6');
body.append('logo_url', 'http://www.bailey.biz/quos-velit-et-fugiat-sunt-nihil-accusantium-harum.html');
body.append('favicon_url', 'https://www.runte.com/ab-provident-perspiciatis-quo-omnis-nostrum-aut-adipisci');
body.append('profile_photo_url', 'https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html');
body.append('social_links[instagram]', 'https://instagram.com/pawscare');
body.append('logo', document.querySelector('input[name="logo"]').files[0]);
body.append('favicon', document.querySelector('input[name="favicon"]').files[0]);
body.append('profile_photo', document.querySelector('input[name="profile_photo"]').files[0]);
body.append('banner_files[]', document.querySelector('input[name="banner_files[]"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Branding
requires authentication
Updates tenant colors, social links, and branding media. Send multipart/form-data with logo, favicon, profile_photo, or banner_files to store assets on the configured filesystem disk, typically S3.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/branding" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "primary_color=#2563eb"\
--form "secondary_color=#14b8a6"\
--form "logo_url=http://www.bailey.biz/quos-velit-et-fugiat-sunt-nihil-accusantium-harum.html"\
--form "favicon_url=https://www.runte.com/ab-provident-perspiciatis-quo-omnis-nostrum-aut-adipisci"\
--form "profile_photo_url=https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html"\
--form "social_links[instagram]=https://instagram.com/pawscare"\
--form "logo=@/tmp/phpOl57M3" \
--form "favicon=@/tmp/phpJkgjvp" \
--form "profile_photo=@/tmp/phpJNbkz9" \
--form "banner_files[]=@/tmp/phpgBjdxb" const url = new URL(
"https://api.vetllama.com/api/tenant/branding"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('primary_color', '#2563eb');
body.append('secondary_color', '#14b8a6');
body.append('logo_url', 'http://www.bailey.biz/quos-velit-et-fugiat-sunt-nihil-accusantium-harum.html');
body.append('favicon_url', 'https://www.runte.com/ab-provident-perspiciatis-quo-omnis-nostrum-aut-adipisci');
body.append('profile_photo_url', 'https://cronin.com/incidunt-iure-odit-et-et-modi-ipsum.html');
body.append('social_links[instagram]', 'https://instagram.com/pawscare');
body.append('logo', document.querySelector('input[name="logo"]').files[0]);
body.append('favicon', document.querySelector('input[name="favicon"]').files[0]);
body.append('profile_photo', document.querySelector('input[name="profile_photo"]').files[0]);
body.append('banner_files[]', document.querySelector('input[name="banner_files[]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Public Config
Get Public Config
requires authentication
Returns template-driven public website content such as homepage sections, FAQs, policies, SEO metadata, and public toggles.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/public-config" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/public-config"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Public Config
requires authentication
Updates flexible public website content for the authenticated tenant.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/public-config" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"contact_details\": {
\"email\": \"gbailey@example.net\",
\"phone\": \"m\"
},
\"is_published\": true,
\"banners\": [
{
\"url\": \"https:\\/\\/www.gulgowski.com\\/nihil-accusantium-harum-mollitia-modi-deserunt\"
}
],
\"faq\": [
{
\"question\": \"architecto\",
\"answer\": \"architecto\"
}
]
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/public-config"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"contact_details": {
"email": "gbailey@example.net",
"phone": "m"
},
"is_published": true,
"banners": [
{
"url": "https:\/\/www.gulgowski.com\/nihil-accusantium-harum-mollitia-modi-deserunt"
}
],
"faq": [
{
"question": "architecto",
"answer": "architecto"
}
]
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Upload Public Config Media
requires authentication
Uploads template-driven public website media such as hero, banner, and section images to the configured filesystem disk.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/public-config/media" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "section_key=about"\
--form "hero_image=@/tmp/phpkFmAe8" \
--form "banner_images[]=@/tmp/phpU1usXA" \
--form "section_images[]=@/tmp/phpPnA6cP" const url = new URL(
"https://api.vetllama.com/api/tenant/public-config/media"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('section_key', 'about');
body.append('hero_image', document.querySelector('input[name="hero_image"]').files[0]);
body.append('banner_images[]', document.querySelector('input[name="banner_images[]"]').files[0]);
body.append('section_images[]', document.querySelector('input[name="section_images[]"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Validate Required Fields
requires authentication
Checks whether the current public content satisfies the selected template's required fields and returns any missing field keys.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/public-config/validate-required-fields" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/public-config/validate-required-fields"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Domains
List Host Mappings
requires authentication
Lists all website hosts mapped to the authenticated tenant, including multiple subdomains and multiple custom domains.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/domains" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/domains"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Add Host Mapping
requires authentication
Adds a tenant website host mapping. Use type=subdomain with subdomain, or type=custom_domain with host.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/domains" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"host\": \"paws-care.com\",
\"domain\": \"b\",
\"subdomain\": \"paws-care\",
\"label\": \"n\",
\"type\": \"subdomain\",
\"is_primary\": true,
\"is_active\": true
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/domains"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"host": "paws-care.com",
"domain": "b",
"subdomain": "paws-care",
"label": "n",
"type": "subdomain",
"is_primary": true,
"is_active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Sync Host Mappings
requires authentication
Replaces the tenant's editable website host mappings from frontend-provided arrays. Existing mappings omitted from subdomains and domains are deactivated. Existing submitted mappings are reactivated.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/domains/sync" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"subdomains\": [
\"paws-care\",
\"londonpets\"
],
\"domains\": [
\"pawscare.com\",
\"telepaws.co.uk\"
],
\"primary_host\": \"paws-care.vetllama.test\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/domains/sync"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"subdomains": [
"paws-care",
"londonpets"
],
"domains": [
"pawscare.com",
"telepaws.co.uk"
],
"primary_host": "paws-care.vetllama.test"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Host mappings synced.",
"data": [
{
"id": 1,
"host": "paws-care.vetllama.test",
"domain": "paws-care.vetllama.test",
"label": "paws-care",
"subdomain": "paws-care",
"type": "subdomain",
"is_primary": true,
"is_active": true,
"is_verified": true
},
{
"id": 2,
"host": "pawscare.com",
"domain": "pawscare.com",
"label": null,
"subdomain": null,
"type": "custom_domain",
"is_primary": false,
"is_active": true,
"is_verified": false
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Host Mapping
requires authentication
Updates host mapping status, verification metadata, or primary flag for a tenant-owned website host.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/domains/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"host\": \"paws-care.com\",
\"domain\": \"b\",
\"subdomain\": \"paws-care\",
\"label\": \"n\",
\"type\": \"subdomain\",
\"is_primary\": true,
\"is_active\": true
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/domains/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"host": "paws-care.com",
"domain": "b",
"subdomain": "paws-care",
"label": "n",
"type": "subdomain",
"is_primary": true,
"is_active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Verification Details
requires authentication
Returns DNS TXT verification instructions and current status for a tenant custom domain.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/domains/16/verification" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/domains/16/verification"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Check Domain Verification
requires authentication
Triggers a DNS TXT verification check for a tenant custom domain and updates its verification state.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/domains/16/verification/check" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/domains/16/verification/check"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Set Primary Host Mapping
requires authentication
Marks this mapped host as the tenant's primary public host and clears other primary flags.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/domains/16/primary" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/domains/16/primary"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Deactivate Host Mapping
requires authentication
Deactivates a tenant website host mapping without removing historical configuration.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/domains/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/domains/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Locations
List Locations
requires authentication
Lists physical visit locations for the authenticated tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/locations" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/locations"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create Location
requires authentication
Creates a physical location that can be linked to physical visit services.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/locations" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"address_line_1\": \"n\",
\"address_line_2\": \"g\",
\"city\": \"z\",
\"state\": \"m\",
\"country\": \"i\",
\"postal_code\": \"y\",
\"latitude\": -89,
\"longitude\": -179,
\"contact_phone\": \"l\",
\"instructions\": \"architecto\",
\"is_primary\": false,
\"is_active\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/locations"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"address_line_1": "n",
"address_line_2": "g",
"city": "z",
"state": "m",
"country": "i",
"postal_code": "y",
"latitude": -89,
"longitude": -179,
"contact_phone": "l",
"instructions": "architecto",
"is_primary": false,
"is_active": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show Location
requires authentication
Returns one tenant-owned location.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/locations/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/locations/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Location
requires authentication
Updates a tenant-owned physical location.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/locations/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"address_line_1\": \"n\",
\"address_line_2\": \"g\",
\"city\": \"z\",
\"state\": \"m\",
\"country\": \"i\",
\"postal_code\": \"y\",
\"latitude\": -89,
\"longitude\": -179,
\"contact_phone\": \"l\",
\"instructions\": \"architecto\",
\"is_primary\": true,
\"is_active\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/locations/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"address_line_1": "n",
"address_line_2": "g",
"city": "z",
"state": "m",
"country": "i",
"postal_code": "y",
"latitude": -89,
"longitude": -179,
"contact_phone": "l",
"instructions": "architecto",
"is_primary": true,
"is_active": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete Location
requires authentication
Deactivates a tenant-owned location.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/locations/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/locations/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Services
List Services
requires authentication
Lists tenant service offerings, including their duration and pricing options.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/services" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/services"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create Service
requires authentication
Creates a service offering for physical visits, telehealth, or instant consult configuration.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/services" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"physical_visit\",
\"name\": \"b\",
\"description\": \"Eius et animi quos velit et.\",
\"is_enabled\": false,
\"delivery_mode\": \"v\",
\"sort_order\": 42,
\"status\": \"active\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/services"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "physical_visit",
"name": "b",
"description": "Eius et animi quos velit et.",
"is_enabled": false,
"delivery_mode": "v",
"sort_order": 42,
"status": "active"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Show Service
requires authentication
Returns one tenant-owned service offering with duration and pricing options.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/services/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/services/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Service
requires authentication
Updates a tenant-owned service offering.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/services/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"instant_consult\",
\"name\": \"b\",
\"description\": \"Eius et animi quos velit et.\",
\"is_enabled\": true,
\"delivery_mode\": \"v\",
\"sort_order\": 42,
\"status\": \"active\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/services/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "instant_consult",
"name": "b",
"description": "Eius et animi quos velit et.",
"is_enabled": true,
"delivery_mode": "v",
"sort_order": 42,
"status": "active"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete Service
requires authentication
Archives a tenant-owned service offering.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/services/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/services/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Service Durations & Pricing
List Service Durations
requires authentication
Lists pricing and duration options for a tenant-owned service.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/services/16/durations" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/services/16/durations"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create Service Duration
requires authentication
Creates a pricing and duration option for a tenant-owned service.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/services/16/durations" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"duration_minutes\": 1,
\"price\": 39,
\"currency\": \"gzm\",
\"is_default\": false,
\"is_active\": true
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/services/16/durations"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"duration_minutes": 1,
"price": 39,
"currency": "gzm",
"is_default": false,
"is_active": true
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Service Duration
requires authentication
Updates a pricing and duration option for a tenant-owned service.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/services/16/durations/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"duration_minutes\": 1,
\"price\": 39,
\"currency\": \"gzm\",
\"is_default\": true,
\"is_active\": true
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/services/16/durations/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"duration_minutes": 1,
"price": 39,
"currency": "gzm",
"is_default": true,
"is_active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete Service Duration
requires authentication
Deactivates a pricing and duration option.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/services/16/durations/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/services/16/durations/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Availability
List Availability
requires authentication
Lists weekly recurring availability windows for the authenticated tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/availability" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/availability"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create Availability
requires authentication
Creates a weekly recurring availability window for a tenant, service, or location.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/availability" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"day_of_week\": 1,
\"start_time\": \"11:23\",
\"end_time\": \"2052-06-26\",
\"timezone\": \"Asia\\/Ulaanbaatar\",
\"is_active\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/availability"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"day_of_week": 1,
"start_time": "11:23",
"end_time": "2052-06-26",
"timezone": "Asia\/Ulaanbaatar",
"is_active": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Availability
requires authentication
Updates a weekly recurring availability window.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/availability/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"day_of_week\": 1,
\"start_time\": \"11:23\",
\"end_time\": \"2052-06-26\",
\"timezone\": \"Asia\\/Ulaanbaatar\",
\"is_active\": true
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/availability/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"day_of_week": 1,
"start_time": "11:23",
"end_time": "2052-06-26",
"timezone": "Asia\/Ulaanbaatar",
"is_active": true
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete Availability
requires authentication
Deactivates a weekly recurring availability window.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/availability/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/availability/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Availability Exceptions
List Availability Exceptions
requires authentication
Lists blocked dates or one-off availability exceptions for the authenticated tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/availability-exceptions" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/availability-exceptions"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create Availability Exception
requires authentication
Creates a full-day or partial-day blocked date for a tenant, service, or location.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/availability-exceptions" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"specific_date\": \"2026-06-03T11:23:05\",
\"start_time\": \"11:23\",
\"end_time\": \"2052-06-26\",
\"reason\": \"n\",
\"full_day\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/availability-exceptions"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"specific_date": "2026-06-03T11:23:05",
"start_time": "11:23",
"end_time": "2052-06-26",
"reason": "n",
"full_day": false
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Availability Exception
requires authentication
Updates a blocked date or availability exception.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/availability-exceptions/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"specific_date\": \"2026-06-03T11:23:05\",
\"start_time\": \"11:23\",
\"end_time\": \"2052-06-26\",
\"reason\": \"n\",
\"full_day\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/availability-exceptions/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"specific_date": "2026-06-03T11:23:05",
"start_time": "11:23",
"end_time": "2052-06-26",
"reason": "n",
"full_day": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete Availability Exception
requires authentication
Deletes a blocked date or availability exception.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/availability-exceptions/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/availability-exceptions/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Booking Policies
Get Booking Policies
requires authentication
Returns booking rule configuration for the authenticated tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/booking-policies" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/booking-policies"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Booking Policies
requires authentication
Updates booking rule configuration such as advance notice, buffers, cancellation, and reschedule settings.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/booking-policies" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"timezone\": \"Asia\\/Yekaterinburg\",
\"min_advance_notice_minutes\": 39,
\"max_advance_booking_days\": 7,
\"buffer_before_minutes\": 12,
\"buffer_after_minutes\": 77,
\"cancellation_cutoff_hours\": 8,
\"reschedule_cutoff_hours\": 76,
\"slot_interval_minutes\": 14,
\"default_booking_status\": \"pending\",
\"allow_cancellation\": false,
\"allow_reschedule\": false
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/booking-policies"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"timezone": "Asia\/Yekaterinburg",
"min_advance_notice_minutes": 39,
"max_advance_booking_days": 7,
"buffer_before_minutes": 12,
"buffer_after_minutes": 77,
"cancellation_cutoff_hours": 8,
"reschedule_cutoff_hours": 76,
"slot_interval_minutes": 14,
"default_booking_status": "pending",
"allow_cancellation": false,
"allow_reschedule": false
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Licenses & Certifications
List Licenses
requires authentication
Lists tenant licenses, certifications, and prescribing eligibility metadata.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/licenses" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/licenses"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create License
requires authentication
Creates a tenant license or certification record. Send multipart/form-data with file to upload a PDF or image document to the configured filesystem disk.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/licenses" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "type=professional"\
--form "title=Veterinary Practice License"\
--form "license_number=VET-2026-001"\
--form "issuing_authority=b"\
--form "issue_date=2026-06-03T11:23:05"\
--form "expiry_date=2052-06-26"\
--form "can_prescribe="\
--form "notes=architecto"\
--form "is_active="\
--form "verification_status=pending"\
--form "file=@/tmp/phpoCktT6" const url = new URL(
"https://api.vetllama.com/api/tenant/licenses"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('type', 'professional');
body.append('title', 'Veterinary Practice License');
body.append('license_number', 'VET-2026-001');
body.append('issuing_authority', 'b');
body.append('issue_date', '2026-06-03T11:23:05');
body.append('expiry_date', '2052-06-26');
body.append('can_prescribe', '');
body.append('notes', 'architecto');
body.append('is_active', '');
body.append('verification_status', 'pending');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update License
requires authentication
Updates a tenant license or certification record. Send multipart/form-data with file to replace the stored document.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/licenses/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "type=professional"\
--form "title=Veterinary Practice License"\
--form "license_number=VET-2026-001"\
--form "issuing_authority=b"\
--form "issue_date=2026-06-03T11:23:05"\
--form "expiry_date=2052-06-26"\
--form "can_prescribe=1"\
--form "notes=architecto"\
--form "is_active="\
--form "verification_status=pending"\
--form "file=@/tmp/phpLQC814" const url = new URL(
"https://api.vetllama.com/api/tenant/licenses/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('type', 'professional');
body.append('title', 'Veterinary Practice License');
body.append('license_number', 'VET-2026-001');
body.append('issuing_authority', 'b');
body.append('issue_date', '2026-06-03T11:23:05');
body.append('expiry_date', '2052-06-26');
body.append('can_prescribe', '1');
body.append('notes', 'architecto');
body.append('is_active', '');
body.append('verification_status', 'pending');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "PUT",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Delete License
requires authentication
Deactivates a tenant license or certification record.
Example request:
curl --request DELETE \
"https://api.vetllama.com/api/tenant/licenses/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/licenses/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "DELETE",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update License
requires authentication
Updates a tenant license or certification record. Send multipart/form-data with file to replace the stored document.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/licenses/16" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: multipart/form-data" \
--header "Accept: application/json" \
--form "type=professional"\
--form "title=Veterinary Practice License"\
--form "license_number=VET-2026-001"\
--form "issuing_authority=b"\
--form "issue_date=2026-06-03T11:23:05"\
--form "expiry_date=2052-06-26"\
--form "can_prescribe=1"\
--form "notes=architecto"\
--form "is_active=1"\
--form "verification_status=pending"\
--form "file=@/tmp/phplLk8PB" const url = new URL(
"https://api.vetllama.com/api/tenant/licenses/16"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "multipart/form-data",
"Accept": "application/json",
};
const body = new FormData();
body.append('type', 'professional');
body.append('title', 'Veterinary Practice License');
body.append('license_number', 'VET-2026-001');
body.append('issuing_authority', 'b');
body.append('issue_date', '2026-06-03T11:23:05');
body.append('expiry_date', '2052-06-26');
body.append('can_prescribe', '1');
body.append('notes', 'architecto');
body.append('is_active', '1');
body.append('verification_status', 'pending');
body.append('file', document.querySelector('input[name="file"]').files[0]);
fetch(url, {
method: "POST",
headers,
body,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Payment Configuration
Get Payment Configuration
requires authentication
Returns tenant payment provider configuration and connection status.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/payment-config" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update Payment Configuration
requires authentication
Updates payment provider configuration. Secrets are encrypted at rest and omitted from responses.
Example request:
curl --request PUT \
"https://api.vetllama.com/api/tenant/payment-config" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"provider\": \"b\",
\"mode\": \"live\",
\"connected_account_id\": \"n\",
\"publishable_key\": \"g\",
\"secret_key\": \"architecto\",
\"webhook_secret\": \"architecto\",
\"charges_enabled\": false,
\"payouts_enabled\": true,
\"details_submitted\": true,
\"onboarding_completed_at\": \"2026-06-03T11:23:05\",
\"status\": \"not_connected\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"provider": "b",
"mode": "live",
"connected_account_id": "n",
"publishable_key": "g",
"secret_key": "architecto",
"webhook_secret": "architecto",
"charges_enabled": false,
"payouts_enabled": true,
"details_submitted": true,
"onboarding_completed_at": "2026-06-03T11:23:05",
"status": "not_connected"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Start Stripe Connect Onboarding
requires authentication
Creates or reuses a Stripe connected account and returns an onboarding URL.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/payment-config/stripe/connect" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"return_url\": \"https:\\/\\/owner.vetllama.test\\/settings\\/payments\\/return\",
\"refresh_url\": \"https:\\/\\/owner.vetllama.test\\/settings\\/payments\\/refresh\",
\"country\": \"US\"
}"
const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config/stripe/connect"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"return_url": "https:\/\/owner.vetllama.test\/settings\/payments\/return",
"refresh_url": "https:\/\/owner.vetllama.test\/settings\/payments\/refresh",
"country": "US"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Stripe Connection Status
requires authentication
Returns the locally stored Stripe connection status for this tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/payment-config/stripe/status" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config/stripe/status"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Refresh Stripe Connection Status
requires authentication
Pulls the latest connected-account status from Stripe and stores it locally.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/payment-config/stripe/refresh" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config/stripe/refresh"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Disconnect Stripe
requires authentication
Clears the local Stripe connected-account state. This does not delete the Stripe account.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/payment-config/stripe/disconnect" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/payment-config/stripe/disconnect"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Onboarding Progress
Get Onboarding Status
requires authentication
Returns step-by-step onboarding completion status for the authenticated tenant.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/onboarding/status" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/onboarding/status"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Get Publish Readiness
requires authentication
Returns whether the authenticated tenant has completed the required setup to publish.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/onboarding/publish-readiness" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/onboarding/publish-readiness"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Onboarding / Publish Workflow
Get Publish Status
requires authentication
Returns current tenant publication state and publish readiness details.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/tenant/publish/status" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/publish/status"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Publish Tenant
requires authentication
Publishes the tenant website if all readiness requirements are satisfied.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/publish" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/publish"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Unpublish Tenant
requires authentication
Removes the tenant website from public published status without deleting configuration.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/unpublish" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/unpublish"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Pause Tenant
requires authentication
Pauses public tenant availability while keeping setup data intact.
Example request:
curl --request POST \
"https://api.vetllama.com/api/tenant/pause" \
--header "Authorization: Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/tenant/pause"
);
const headers = {
"Authorization": "Bearer {ADMIN_OR_TENANT_OWNER_OR_END_USER_JWT}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
User
Auth
Request Magic Link
Requests a one-time magic sign-in link for an existing EndUser under the resolved tenant. This endpoint never creates users and always returns a generic success response so email existence is not exposed.
Use Host: demo.vetllama.test in local development when testing against seeded tenant data.
Example request:
curl --request POST \
"https://api.vetllama.com/api/user/auth/magic-link/request" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"jane@example.com\"
}"
const url = new URL(
"https://api.vetllama.com/api/user/auth/magic-link/request"
);
const headers = {
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "jane@example.com"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "If an account exists for that email, a sign-in link has been sent.",
"data": null
}
Example response (404):
{
"success": false,
"message": "Tenant could not be resolved for this host."
}
Example response (429):
{
"message": "Too Many Attempts."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Verify Magic Link
Consumes a valid, single-use, tenant-bound magic-link token and returns an EndUser-scoped JWT. Tokens are stored hashed, expire after 15 minutes, and cannot be reused.
Use Host: demo.vetllama.test in local development when testing against seeded tenant data.
Example request:
curl --request POST \
"https://api.vetllama.com/api/user/auth/magic-link/verify" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"email\": \"jane@example.com\",
\"token\": \"2dc9LW5MsHGpJmw9v72Uw0HppFWlNqHNrHuKxnjIuRtb2UZ2DFbpURkiN0Lr7qkg\",
\"device_token\": \"web-user-device\"
}"
const url = new URL(
"https://api.vetllama.com/api/user/auth/magic-link/verify"
);
const headers = {
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"email": "jane@example.com",
"token": "2dc9LW5MsHGpJmw9v72Uw0HppFWlNqHNrHuKxnjIuRtb2UZ2DFbpURkiN0Lr7qkg",
"device_token": "web-user-device"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged in successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "end_user",
"expires_in": 3600,
"user": {
"id": 1,
"tenant_id": 1,
"name": "Jane Customer",
"email": "jane@example.com",
"phone": null,
"is_active": true
}
}
}
Example response (422):
{
"success": false,
"message": "The given data was invalid.",
"errors": {
"token": [
"This magic link is invalid or has expired."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Logout
requires authentication
Invalidates the current EndUser JWT and closes the latest open auth activity session. Tenant host resolution is still required.
Example request:
curl --request POST \
"https://api.vetllama.com/api/user/auth/logout" \
--header "Authorization: Bearer {END_USER_JWT}" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/user/auth/logout"
);
const headers = {
"Authorization": "Bearer {END_USER_JWT}",
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Logged out successfully.",
"data": null
}
Example response (403):
{
"success": false,
"message": "Unauthorized for this tenant."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Refresh Token
requires authentication
Exchanges a valid EndUser JWT for a fresh EndUser JWT. The token must belong to the tenant resolved from the Host header.
Example request:
curl --request POST \
"https://api.vetllama.com/api/user/auth/refresh" \
--header "Authorization: Bearer {END_USER_JWT}" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/user/auth/refresh"
);
const headers = {
"Authorization": "Bearer {END_USER_JWT}",
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Token refreshed successfully.",
"data": {
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"token_type": "bearer",
"guard": "end_user",
"expires_in": 3600,
"user": {
"id": 1,
"tenant_id": 1,
"email": "jane@example.com"
}
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Current Profile
requires authentication
Returns the authenticated EndUser profile. The token must belong to the tenant resolved from the Host header.
Example request:
curl --request GET \
--get "https://api.vetllama.com/api/user/auth/me" \
--header "Authorization: Bearer {END_USER_JWT}" \
--header "Host: demo.vetllama.test" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://api.vetllama.com/api/user/auth/me"
);
const headers = {
"Authorization": "Bearer {END_USER_JWT}",
"Host": "demo.vetllama.test",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"success": true,
"message": "Profile fetched successfully.",
"data": {
"id": 1,
"tenant_id": 1,
"name": "Jane Customer",
"email": "jane@example.com",
"phone": null,
"is_active": true
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.