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).
Authentication
Primary external auth is Sanctum personal access tokens (Bearer token).
Token permissions currently available:
createreadupdatedelete
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.
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