API Integration
This page documents the current external API contract and operational behavior for programmatic clients.
Contract Scope
Current canonical pet-management contract:
GET /api/my-petsGET /api/my-pets/sectionsPOST /api/petsGET /api/pets/{pet}PUT /api/pets/{pet}PUT /api/pets/{pet}/statusDELETE /api/pets/{pet}POST /api/pets/{pet}/weightsPUT /api/pets/{pet}/weights/{weight}DELETE /api/pets/{pet}/weights/{weight}POST /api/pets/{pet}/medical-recordsPUT /api/pets/{pet}/medical-records/{record}DELETE /api/pets/{pet}/medical-records/{record}POST /api/pets/{pet}/vaccinationsPUT /api/pets/{pet}/vaccinations/{record}POST /api/pets/{pet}/vaccinations/{record}/renewDELETE /api/pets/{pet}/vaccinations/{record}POST /api/pets/{pet}/microchipsPUT /api/pets/{pet}/microchips/{microchip}DELETE /api/pets/{pet}/microchips/{microchip}
Notes:
- The platform currently treats
/api/*as the active v1 contract. PATCH /api/pets/{pet}is not part of the external contract.- Success responses follow the standard envelope:
{ success, data, message? }. - Error responses follow:
{ success: false, data: null, message, error, errors? }(fielderrorsappears for validation failures). POST /api/petsrequirescountry(ISO 3166-1 alpha-2, e.g.VN).GET /api/my-petsandGET /api/my-pets/sectionsinclude a compacthealth_summaryon each pet for list views. This summary currently exposes latest and previous weight values plus aggregate vaccination status so clients can render pet cards without per-pet follow-up requests.
Authentication
Primary external auth is Sanctum personal access tokens (Bearer token).
Token permissions currently available:
pet:readpet:writehealth:readhealth:writeprofile:readcreatereadupdatedelete
New manually created tokens default to read only. The pet:*, health:*, and profile:read scopes are exposed for GPT connector compatibility and domain-oriented integrations; the currently enforced route-level PAT gates below still use the generic create, read, update, and delete abilities.
Token Management (SPA)
Developer UI route:
/developer
JSON endpoints used by the SPA:
GET /api/user/api-tokensPOST /api/user/api-tokensPUT /api/user/api-tokens/{tokenId}DELETE /api/user/api-tokens/{tokenId}
Security behavior:
- Token management is intentionally session-only. Personal access tokens cannot list, create, update, or revoke other tokens, even if they have broad abilities.
- Plaintext token is returned only once on creation.
- Plaintext token is never retrievable later.
- In the
/developerUI, newly created tokens are shown in a dedicated confirmation dialog with copy/download actions until the user confirms they saved the token.
Ability enforcement for PAT clients
The currently enforced programmatic contract is:
readforGET /api/users/mereadforGET /api/my-petsreadforGET /api/my-pets/sectionscreateforPOST /api/petsupdateforPUT /api/pets/{pet}updateforPUT /api/pets/{pet}/statusdeleteforDELETE /api/pets/{pet}createforPOST /api/pets/{pet}/weightsupdateforPUT /api/pets/{pet}/weights/{weight}deleteforDELETE /api/pets/{pet}/weights/{weight}createforPOST /api/pets/{pet}/medical-recordsupdateforPUT /api/pets/{pet}/medical-records/{record}deleteforDELETE /api/pets/{pet}/medical-records/{record}createforPOST /api/pets/{pet}/vaccinationsupdateforPUT /api/pets/{pet}/vaccinations/{record}createforPOST /api/pets/{pet}/vaccinations/{record}/renewdeleteforDELETE /api/pets/{pet}/vaccinations/{record}createforPOST /api/pets/{pet}/microchipsupdateforPUT /api/pets/{pet}/microchips/{microchip}deleteforDELETE /api/pets/{pet}/microchips/{microchip}
Session-authenticated browser requests are not constrained by PAT abilities.
This is the current first slice of explicit PAT support. Other authenticated areas such as notifications, messaging, placement workflows, helper profiles, and some profile-adjacent routes still need an explicit PAT product decision before they should be treated as stable programmatic contract.
Public/optional-auth pet health reads remain public in this slice:
GET /api/pets/{pet}/weightsGET /api/pets/{pet}/weights/{weight}GET /api/pets/{pet}/medical-recordsGET /api/pets/{pet}/medical-records/{record}GET /api/pets/{pet}/vaccinationsGET /api/pets/{pet}/vaccinations/{record}GET /api/pets/{pet}/microchipsGET /api/pets/{pet}/microchips/{microchip}
GPT Auth Bridge
GPT connector OAuth uses these bridge endpoints:
POST /api/gpt-auth/registerPOST /api/gpt-auth/telegram-linkPOST /api/gpt-auth/confirmPOST /api/gpt-auth/exchangePOST /api/gpt-auth/revoke
Important registration semantics:
- The connector does not provide a trusted email address or username from ChatGPT.
- During
/gpt-connect, the user entersnameandemaildirectly into the Meo Mai Moi registration form. - During
/gpt-connect, Google Sign-In returns to the same consent screen via a safe relativeredirectback to/gpt-connect?.... - During
/gpt-connect, Telegram Sign-In usesPOST /api/gpt-auth/telegram-linkto mint a short-lived resume token, then opens the bot with?start=login_<token>. After Telegram auth, the Mini App opens/gpt-connect?...&tg_token=...so the consent step can continue. - If email verification is required,
POST /api/gpt-auth/registerkeeps the account unverified and sends the normal verification email flow. - If email verification is disabled globally, GPT-registered users are marked verified immediately.
- GPT-issued Sanctum tokens are minted only after the authenticated user explicitly confirms the connection.
POST /api/gpt-auth/exchangeandPOST /api/gpt-auth/revokereturn401for an invalid connector API key, and503when the backend connector API key is not configured at all. The latter is treated as server misconfiguration and is logged.
Rate Limits
Rate limiting has two layers:
- Minute-based throttles (middleware)
- Daily user quota (business rule)
Minute-based examples:
- Authenticated API group:
throttle:authenticated(prod 60/min, dev/test/e2e 300/min) - Public listing endpoints:
throttle:public-api(prod 30/min, dev/test/e2e 300/min)
Daily quota:
- Regular users:
1000requests/day by default (configurable) - Premium users: unlimited
- Window boundary: UTC day (
00:00:00to23:59:59UTC)
Over-quota response:
- Status:
429 - Error code:
API_DAILY_QUOTA_EXCEEDED - Includes machine-readable quota metadata and
reset_at_utc
API Request Logging
API requests are persisted to api_request_logs for monitoring and support triage.
Logged fields include:
- Timestamp
- Method/path/route pattern
- Status code
- Auth mode (
pat,session,none) - User id (nullable)
- Quota-denied
429responses from the daily API quota middleware
Retention:
- Default: 30 days (configurable)
- Pruning command:
php artisan api-logs:prune - Scheduled daily via
routes/console.php
Configuration
Config defaults:
backend/config/api.php
Runtime-configurable settings (via system settings UI):
api_daily_quota_regularapi_request_logs_retention_days