MaIA Scan

MaIA API · v1 · technical documentation

MaIA API: skin and hair analysis from a selfie and a makeup simulator, over HTTP.

One key, three operations. MaIA Scan returns skin tone and undertone, hair colour and hair type from a photo; MaIA Try-On returns the same photo with lipstick — a preset shade or any #RRGGBB colour of your brand — or with foundation applied. This page describes exactly what the gateway at maiascan.ai/api accepts and returns: fields, headers, error codes and limits, with examples in curl, Node.js and Python.

Request · one selfie

curl -X POST https://maiascan.ai/api/v1/scan \
  -H "Authorization: Bearer msk_live_…" \
  -F "front=@selfie.jpg" \
  -F "models=skin,hair_color,hair_type"

Response · the beauty profile

POST /api/v1/scan → 200
{
  "profile": {
    "skin_tone": { "value": "medium", "confidence": 0.94 },
    "skin_undertone": { "value": "warm", "confidence": 0.91 },
    "hair_color": { "value": "dark brown", "confidence": 0.88 },
    "hair_pattern": { "value": "curly", "confidence": 0.90 }
  },
  "model_version": "478 landmarks · v0.5",
  "retained": false
}

Overview

The MaIA API is the HTTPS gateway B4A exposes at maiascan.ai for the photo-based MaIA products. You authenticate with a key from your account, send a photo as multipart/form-data and get the answer synchronously: a beauty profile in JSON (MaIA Scan — skin tone and undertone, hair colour and hair type, choosing which models to run) or the same photo as a PNG with the product applied (MaIA Try-On — lipstick in preset shades or any colour of your brand, and foundation as a makeup simulator). The models are experimental: the response carries a status per attribute and flags when the person should confirm the result.

Nothing is assumed about your stack: any HTTP client that can send multipart works. No mandatory SDK, no webhook, no session state — the response of the call is the result. The analysis is cosmetic and photo-based: it is not a diagnosis, does no facial recognition and does not identify people.

Availability of the MaIA products
ProductAvailabilityEndpointDescription
MaIA ScanSelf-service via APIPOST /api/v1/scanSkin and hair profile in JSON from a front-facing selfie (optional side photo): skin tone and undertone, hair colour and hair type. You choose which models to run in the models field.
MaIA Try-On — lipstickSelf-service via APIPOST /api/v1/try-onThe customer's photo comes back as a PNG with the lipstick applied: six preset shades (shade) or any colour of your brand as #RRGGBB (color), with matte, satin or gloss finish and adjustable intensity.
MaIA Try-On — foundation (makeup simulator)Self-service via APIPOST /api/v1/try-oncategory=foundation: the same photo with a foundation in the colour you send (#RRGGBB), with adjustable intensity. Same endpoint, same key.
MaIA Beauty AdvisorAs a project—Not a self-service endpoint. Delivered by B4A as a project — on the brand's WhatsApp, as a product-page widget or in chat — on top of the same profile data MaIA Scan returns and your brand's integrated catalogue.

Start in four steps

  1. Create the account

    Sign in with Google, e-mail and password, or receive a magic link by e-mail. No manual approval — and the full documentation PDF, with the price list, is already available in your account.

    Create account
  2. Buy a credit package

    Starter (500 credits), Growth (2,500) or Scale (10,000) — pay by card, Pix or boleto in our own checkout. Credits never expire.

    See packages
  3. Create the API key

    Key creation unlocks after the first purchase. The key (msk_live_…) is shown once — copy it into your secrets vault.

    My account
  4. Make the first call

    Send a selfie to POST /api/v1/scan (choosing the models in models) or a photo with shade/color, finish and intensity to POST /api/v1/try-on. The answer arrives in the same request.

curl -X POST https://maiascan.ai/api/v1/scan \
  -H "Authorization: Bearer msk_live_…" \
  -H "x-request-id: order-8841" \
  -F "front=@selfie.jpg;type=image/jpeg" \
  -F "side=@profile.jpg;type=image/jpeg" \
  -F "models=skin,hair_color,hair_type"
# models is optional: omit it for the complete scan, or send e.g. "models=skin"

Authentication

Every route under /api/v1 requires the Authorization header with an API key in Bearer format. The key identifies the account (and therefore the credit balance) and the key itself — usage is recorded per key. Your key never leaves the gateway: calls to the model are made with B4A's credential, on behalf of your account.

Authorization: Bearer msk_live_…
  • Format: msk_live_ followed by 32 alphanumeric characters. We store only the SHA-256 hash and a display prefix; the full text is shown once, at creation.
  • Up to 10 active keys per account. Revoke any key at any time in the portal (My account → API keys); revocation applies to the next call.
  • Missing, invalid or revoked key: 401 with { "error": "invalid_api_key" }.
  • Use the key on the server only. Never embed it in browser code or a distributed app — whoever holds the key spends your credits.
  • Optional header x-end-user-id (up to 160 characters: letters, digits and @ . _ : + -): your end customer's identifier, forwarded to the model for your own reconciliation. Outside that format it is ignored, never rejected.

Credits

Credits are consumed per operation: a MaIA Scan analysis charges for the models you chose to run (and only those that returned a value), and every image rendered by MaIA Try-On — lipstick or foundation — charges its operation. The credit is reserved before we call the model and settled when the answer arrives; if the model fails, or a scan model cannot predict anything, the corresponding part is refunded automatically. You never pay for a result you did not receive, and we never process a photo we cannot charge.

The current price list (how many credits each operation costs) and the complete technical documentation as a PDF live in the account area, available to any login — even before the first purchase.

PackagePriceCredits
StarterR$ 998500
GrowthR$ 1,9982,500
ScaleR$ 4,99810,000

Credits never expire. One-off and automatic top-ups follow your last paid package. Enterprise: talk to us.

  • The balance after the call comes with every successful response: credits_charged and credits_remaining in the scan JSON and the X-Credits-Charged and X-Credits-Remaining headers on both endpoints.
  • Insufficient balance: the call is refused before any processing with 402 and { "error": "insufficient_credits", "balance": 2, "required": 3 }. The attempt is recorded in your usage, without a charge.
  • Auto top-up: in the portal you set a threshold and an amount; when the balance drops below it, we create an order and e-mail the payment link (we never charge the card without you).

Price list and documentation PDF

The credits-per-operation table and the PDF with this whole documentation — including the attribute vocabularies and ready-to-run examples — live in your account, no purchase needed.

POST/api/v1/scan

Send a front-facing selfie (and optionally a side photo) and receive the person's beauty profile in JSON: skin tone and undertone, hair colour and hair type — only the models you ask for. Synchronous: the response is the result.

Request

multipart/form-data body with the fields below (unknown text fields are refused with 400). Headers: Authorization (required), x-request-id and x-end-user-id (optional).

FieldTypeRequiredDescription
frontfileyesFront-facing photo of the face. Content-Type image/jpeg or image/png (we check the bytes too). Up to 6 MiB. Recommended short side of 480 px or more — below that the model may abstain.
sidefileoptionalSide (profile) photo of the same person, same types and limit. Sent in the same call at no extra cost; helps the hair models.
modelstextoptionalWhich models to run, comma-separated: skin, hair_color, hair_type (any combination, no repeats). Omitted = the complete analysis with all three. Unknown value: 422 invalid_selection, nothing charged.
x-request-idheaderoptionalYour request identifier (up to 80 characters). Stored on the usage event for reconciliation; it does not deduplicate calls.
x-end-user-idheaderoptionalYour end customer's identifier (up to 160 characters, no spaces), forwarded to the model. Outside the format it is ignored.

Models and attributes

Each model returns one or two attributes. The models field accepts the ids in the first column; the response carries, in result.attributes, exactly the attributes of the requested models.

ModelDescriptionAttribute
skinSkin — Skin tone in nine levels (very_light … deep) and undertone (cool, neutral, warm).skin_tone, skin_undertone
hair_colorHair colour — Nine categories, from black to light_blonde, plus red, gray_white and other.hair_color
hair_typeHair type — Strand pattern: straight, wavy, curly or coily.hair_pattern

Response

200 OK, application/json. The envelope is fixed; result is the document returned by the model, passed through as-is. The same numbers come in the X-Session-Id, X-Request-Id, X-Credits-Charged and X-Credits-Remaining headers.

FieldTypeDescription
session_idstringIdentifier of the usage event (the charged session). Keep it for support and reconciliation.
request_idstringIdentifier of the request in the MaIA service. Quote both ids when talking to support.
credits_chargedintegerCredits actually charged for this call — the models that returned at least one predicted attribute.
credits_remainingintegerAccount balance after this call.
modelsstring[]Requested models, in canonical order (skin, hair_color, hair_type).
models_deliveredstring[]Models that returned at least one attribute with status predicted — the ones that were charged.
result.attributes.<attribute>objectPer requested attribute: status (predicted, abstained or unsupported), value (the vocabulary value), score (uncalibrated softmax — not an accuracy), model_version, photo_roles and requires_confirmation.
result.quality / result.experimental / result.requires_confirmationobject · booleanPhoto-quality diagnostics per role (front, side) and the model flags. The models are experimental: ask the person to confirm before using a value in a purchase decision.
Response
HTTP/1.1 200 OK
Content-Type: application/json
X-Session-Id: cmg1x3k9h0001abcd
X-Request-Id: 8f1c2e7a-…
X-Credits-Charged: 3
X-Credits-Remaining: 497

{
  "session_id": "cmg1x3k9h0001abcd",
  "request_id": "8f1c2e7a-…",
  "credits_charged": 3,
  "credits_remaining": 497,
  "models": ["skin", "hair_color", "hair_type"],
  "models_delivered": ["skin", "hair_color", "hair_type"],
  "result": {
    "attributes": {
      "skin_tone":      { "status": "predicted", "value": "light_medium", "score": 0.41, "score_kind": "uncalibrated_softmax_not_accuracy", "requires_confirmation": true, "photo_roles": ["front"] },
      "skin_undertone": { "status": "predicted", "value": "warm",         "score": 0.52, "requires_confirmation": true },
      "hair_color":     { "status": "predicted", "value": "dark_brown",   "score": 0.63, "requires_confirmation": true },
      "hair_pattern":   { "status": "abstained" }
    },
    "quality": { "front": { … } },
    "requires_confirmation": true,
    "experimental": true
  }
}

Status of each attribute

A 200 may contain abstentions. Only what was predicted is charged:

StatusMeaning
predictedThe model returned a vocabulary value (value) with its score. The corresponding model is charged.
abstainedThe model was not confident enough on this photo (lighting, framing, resolution). Not charged.
unsupportedThe attribute cannot be assessed on this photo (for example, covered hair). Not charged.

Errors

StatusCodeMeaningCredit charged?
400front_requiredThe front field was not sent.no
400—Unknown text field (body validation).no
401invalid_api_keyMissing, invalid or revoked key.no
402insufficient_creditsBalance below what the requested models need; the body carries balance and required.no
413photo_too_largeImage above 6 MiB. Uploads far above the limit are cut at reception with a generic 413.no
415unsupported_media_typeContent-Type of one of the files other than image/jpeg or image/png.no
422unsupported_photoThe bytes are not JPEG or PNG (or the file is empty).no
422invalid_selectionmodels contains an unknown id.no
422bad_photoThe model refused the photo (no face detected, photo too small). Credits refunded.no
422unusable_photoNo attribute could be predicted (all abstained or unsupported). Everything refunded; the body carries session_id and request_id.no
429rate_limitedMore than 20 requests per minute with the same key (or the service is at its limit). Retry-After header in seconds.no
503upstream_unavailableThe model did not answer (failure or 180 s wait). Credits refunded; the body carries session_id.no
503upstream_not_configuredThe analysis service is not connected on this environment. Nothing is charged.no

Limits

  • Up to 6 MiB per file, at most 2 files (front + side), static JPEG or PNG.
  • Synchronous call; the gateway waits for the model for up to 180 s. Give your HTTP client at least 200 s.
  • 20 requests per minute per API key and 120 per minute per source IP.

Consent is mandatory: obtain the person's explicit authorisation before sending the photo (LGPD). MaIA Scan does no facial recognition or identification; it returns a cosmetic, experimental analysis for personalisation — not a diagnosis. Fields with requires_confirmation must be confirmed with the person.

Examples

curl -X POST https://maiascan.ai/api/v1/scan \
  -H "Authorization: Bearer msk_live_…" \
  -H "x-request-id: order-8841" \
  -F "front=@selfie.jpg;type=image/jpeg" \
  -F "side=@profile.jpg;type=image/jpeg" \
  -F "models=skin,hair_color,hair_type"
# models is optional: omit it for the complete scan, or send e.g. "models=skin"

POST/api/v1/try-on

Send a front-facing photo with the product to apply and receive the same photo as a PNG. Lipstick (category=lipstick, default): a preset shade (shade) or any colour of your brand (color, #RRGGBB), with finish and intensity. Foundation (category=foundation): an #RRGGBB colour with intensity. Only the makeup area changes. Synchronous.

Request

multipart/form-data body with the fields below (unknown text fields are refused with 400). Headers: Authorization (required), x-request-id and x-end-user-id (optional).

FieldTypeRequiredDescription
photofileyesFront-facing photo, JPEG or PNG (we check the bytes, not just the Content-Type). Up to 6 MiB; short side of at least 320 px; mouth visible for lipstick.
categorytextoptionallipstick (default) or foundation.
shadetextoptionalLipstick: one of the preset shades — rose, red, berry, coral, plum or nude (see GET /api/v1/try-on/shades). Exactly one of shade and color.
colortextoptionalAny colour as #RRGGBB (upper or lower case). Lipstick: alternative to shade, for your brand's palette. Foundation: required.
finishtextoptionalLipstick: matte (default), satin or gloss. Not applicable to foundation.
intensitytextoptionalInteger from 0 to 100. Default 100 for lipstick and 70 for foundation.
x-request-idheaderoptionalYour request identifier (up to 80 characters), stored on the usage event.

Your brand's colour

Instead of a preset shade, send color=#RRGGBB with your product's hex — the model applies exactly that colour, at the requested finish and intensity. This is the way to try your own palette without a calibration project.

Lipstick with your brand's colour (curl)
curl -X POST https://maiascan.ai/api/v1/try-on \
  -H "Authorization: Bearer msk_live_…" \
  -F "photo=@selfie.jpg;type=image/jpeg" \
  -F "color=#993355" \
  -F "finish=satin" \
  -F "intensity=85" \
  -o try-on.png
# exactly one of shade / color; X-TryOn-Color echoes the normalised colour (#993355)

Foundation (makeup simulator)

category=foundation applies a foundation in the colour given in color, with intensity (default 70). There is no shade or finish for foundation. Same key, same endpoint, same receipt in the headers.

Foundation — makeup simulator (curl)
curl -X POST https://maiascan.ai/api/v1/try-on \
  -H "Authorization: Bearer msk_live_…" \
  -F "photo=@selfie.jpg;type=image/jpeg" \
  -F "category=foundation" \
  -F "color=#C68642" \
  -F "intensity=70" \
  -o foundation.png
# no shade / finish for foundation; X-TryOn-Category: foundation

Response

200 OK, image/png — the body is the rendered image. The receipt travels in the headers:

HeaderDescription
X-Session-IdIdentifier of the usage event (the charged session).
X-Request-IdIdentifier of the request in the MaIA service.
X-Credits-ChargedCredits charged for this image.
X-Credits-RemainingAccount balance after this call.
X-TryOn-Categorythe category rendered: lipstick, foundation, blush, … or full_look.
X-TryOn-ColorThe colour applied, as upper-case #RRGGBB — the preset's hex or your normalised colour.
X-TryOn-FinishThe finish applied (lipstick only). There is no fallback: what you asked for is what was applied.
X-Model-VersionVersion of the render model, when reported.
Cache-Controlno-store. The image is not kept in any cache on our side.
Response
HTTP/1.1 200 OK
Content-Type: image/png
Cache-Control: no-store
X-Session-Id: cmg1x4p2r0002efgh
X-Request-Id: 2b7d9f10-…
X-Credits-Charged: 1
X-Credits-Remaining: 496
X-TryOn-Category: lipstick
X-TryOn-Color: #B85C75
X-TryOn-Finish: gloss
X-Model-Version: lipstick-custom-srgb-v1

<PNG bytes>

Errors

StatusCodeMeaningCredit charged?
400photo_requiredThe photo field was not sent.no
400—Unknown or malformed text field (body validation).no
401invalid_api_keyMissing, invalid or revoked key.no
402insufficient_creditsInsufficient balance; the body carries balance and required.no
413photo_too_largePhoto above 6 MiB. Uploads far above the limit are cut at reception with a generic 413.no
422invalid_selectioncategory, shade, color, finish or intensity outside the contract (e.g. shade and color together, colour not #RRGGBB, foundation without color). The body says which.no
422unsupported_photoThe bytes are not JPEG or PNG (or the file is empty).no
422bad_photoThe model refused the photo (face not frontal, mouth not visible, short side below 320 px). Credit refunded.no
429rate_limitedMore than 20 requests per minute with the same key (or the service is at its limit). Retry-After header in seconds.no
503upstream_unavailableThe render service failed or did not answer within 180 s. Credit refunded; try again in a moment.no
503upstream_not_configuredThe render service is not connected on this environment. Nothing is charged.no

Limits

  • JPEG or PNG, up to 6 MiB, short side ≥ 320 px.
  • Synchronous call; the gateway waits for the model for up to 180 s. Give your HTTP client at least 200 s.
  • 20 requests per minute per API key and 120 per minute per source IP.
  • Simulated colour may differ from the real product: the render is experimental and works in sRGB from the given hex. Calibrated palette with human validation and other makeup categories: as a project.

Examples — lipstick with a preset shade

curl -X POST https://maiascan.ai/api/v1/try-on \
  -H "Authorization: Bearer msk_live_…" \
  -F "photo=@selfie.jpg;type=image/jpeg" \
  -F "shade=rose" \
  -F "finish=gloss" \
  -F "intensity=90" \
  -D headers.txt \
  -o try-on.png
# headers.txt now holds X-Session-Id, X-Request-Id, X-Credits-Charged, X-Credits-Remaining, X-TryOn-Color, X-TryOn-Finish

GET/api/v1/try-on/shades

Lists what POST /api/v1/try-on accepts: the preset shades with their reference hex, the finishes, the custom-colour format, the intensity ranges, the categories and the upload ceiling. No credit consumed.

Response

200 OK, application/json, Cache-Control: private, max-age=3600. Requires the same key (401 without it).

FieldTypeDescription
shades[].idstringValue accepted in the try-on shade field.
shades[].hexstringReference colour of the shade (#RRGGBB) to show in your UI.
finishesstring[]Values accepted in the finish field (lipstick).
custom_colorbooleantrue: the color field accepts any colour of your brand.
color_formatstringFormat accepted in color: #RRGGBB.
intensityobjectRange and default of the lipstick intensity: { min, max, default }.
foundation_intensityobjectRange and default of the foundation intensity: { min, max, default }.
categoriesstring[]Values accepted in category: lipstick, foundation.
max_upload_bytesintegerPhoto upload ceiling in bytes (6 MiB).
Response
{
  "shades": [
    { "id": "rose",  "hex": "#B85C75" },
    { "id": "red",   "hex": "#B8293D" },
    { "id": "berry", "hex": "#883252" },
    { "id": "coral", "hex": "#D96758" },
    { "id": "plum",  "hex": "#703B5B" },
    { "id": "nude",  "hex": "#AF786F" }
  ],
  "finishes": ["matte", "satin", "gloss"],
  "custom_color": true,
  "color_format": "#RRGGBB",
  "intensity": { "min": 0, "max": 100, "default": 100 },
  "foundation_intensity": { "min": 0, "max": 100, "default": 70 },
  "categories": ["lipstick", "foundation"],
  "max_upload_bytes": 6291456
}

Examples

curl https://maiascan.ai/api/v1/try-on/shades \
  -H "Authorization: Bearer msk_live_…"

Browser SDK (early access)

Beyond the photo API, MaIA Try-On exists as a browser SDK: thirteen simulators (lipstick, foundation, blush, powder, concealer, eyeshadow, mascara, eyebrows, eyeliner, bronzer, contour, highlighter and lip liner) and a Full Look, live through the camera or from a photo, rendered locally on the customer's device. No image is uploaded; your brand hosts the immutable bundle on its own origin.

The SDK never calls this API on its own. Lipstick and foundation can get a final server render — through the endpoint above, with the account key server-side — charged in credits like any call; the other products and Full Look are local previews. The integration guide (JavaScript, React, Angular, CSP, privacy, versions) lives in the signed-in area, and access is enabled account by account.

How to get the SDK today

  1. Create an account on maiascan.ai (e-mail or Google) and open My account → SDK.
  2. Click "Request access": the SDK is in early access and the B4A team enables it account by account. B4A internal teams: ask Jan directly.
  3. Once enabled, the same page shows the current version, its SHA-256 and the "Download bundle" button (package.tgz). Host the contents of package/ on your origin at /vendor/maia-try-on/<version>/ — the SDK needs same-origin workers, WASM and models.
  4. npm: once enabled, npm i @maiascan/try-on works through our private registry (maiascan.ai/api/npm), authenticated with the account\u2019s API key — the two .npmrc lines are in the signed-in area. No npmjs.com account is needed.
Create an account and request SDK access

Reference: attribute vocabularies

The possible values of value in result.attributes, per attribute. Vocabularies are fixed per API version (api_version in the model envelope); new values arrive as a compatible change.

AttributePossible valuesDescription
skin_tonevery_light, light, light_medium, medium, medium_tan, medium_dark, dark, very_dark, deepNine skin-tone levels, from lightest to deepest.
skin_undertonecool, neutral, warmSkin undertone.
hair_colorblack, dark_brown, medium_brown, light_brown, dark_blonde, light_blonde, red, gray_white, otherPredominant hair colour.
hair_patternstraight, wavy, curly, coilyStrand pattern.

Every attribute comes with status predicted, abstained or unsupported; score is an uncalibrated softmax — treat it as a ranking, not as a probability or an accuracy.

Errors and status codes

Every error is JSON with a stable error field (for your code) and a readable message (for the log). Compare error, not message. No error consumes a credit: when the failure happens after the reservation (422 bad_photo or unusable_photo, 429, 503), the refund is written in the same transaction and the body carries session_id.

StatusMeaning
400Malformed request: required field missing or unknown text field.
401invalid_api_key — missing, invalid or revoked key.
402insufficient_credits — balance below what is needed; the body carries balance and required.
413photo_too_large — image above 6 MiB.
415unsupported_media_type — Content-Type other than image/jpeg or image/png (scan).
422Valid in form, invalid in content: invalid_selection, unsupported_photo, bad_photo, unusable_photo (scan).
429rate_limited — per-key or service limit; wait Retry-After seconds and retry with backoff.
503upstream_unavailable (credit refunded) or upstream_not_configured (nothing charged).
Shape of an error
HTTP/1.1 402 Payment Required
Content-Type: application/json

{
  "error": "insufficient_credits",
  "message": "Buy a credit package to continue.",
  "balance": 2,
  "required": 3
}

Limits, idempotency and x-request-id

  • Rate limit: 20 requests per minute per API key on every /api/v1 route (429 rate_limited with Retry-After), plus 120 per minute per source IP. For higher volumes, talk to us.
  • Idempotency: calls are not idempotent — every 200 consumes credits. Do not automatically retry a call that returned 200; retry only 429 and 503 errors (which do not charge), honouring Retry-After and with exponential backoff.
  • x-request-id: send your identifier (up to 80 characters). It is stored on the usage event and shows in reconciliation; use it together with session_id / X-Session-Id and request_id / X-Request-Id when talking to support.
  • Timeouts: the gateway waits for the model for up to 180 s. Give your HTTP client at least 200 s so it does not abandon a call that will still be charged and answered.

Data handling and consent

  • Consent: you are responsible for obtaining the person's explicit authorisation before sending any photo, under the LGPD. In our own demo the text used is: "I authorise the processing of this photo only to generate the simulation; it is not stored."
  • Photos in the gateway: they live in memory only for the duration of the request and are forwarded once to the model. The gateway writes no photos to disk, database or logs — logs record size, operation, latency, status and request identifiers.
  • In the MaIA service: nothing is retained or used for training (retained: false, used_for_training: false in the envelope). Only the result — JSON or PNG — comes back to you, with Cache-Control: no-store.
  • What we do not do: facial recognition, identification of people, inference of protected traits or medical diagnosis. The analysis is cosmetic and experimental; fields with requires_confirmation must be confirmed with the person.
  • Usage log: per request we keep account, key, endpoint, status, credits, latency, x-request-id and the model's request_id — that is what shows on your usage page.
B4A Privacy Policy →

Base URL, version and contact

https://maiascan.ai/api
  • Base URL: https://maiascan.ai/api — always HTTPS. Public routes live under /v1.
  • Versioning: the version goes in the path (v1). Compatible changes (new JSON fields, new headers, new shades, new vocabulary values) arrive without a version bump; any incompatible change is born as /v2, with /v1 kept in parallel for an announced period.
  • Gateway status: GET https://maiascan.ai/api/health returns { "status": "ok", "commit": "…" } — no authentication.
  • Technical and commercial support: comercial@b4a.ai.

Need more volume, higher per-key limits, a calibrated palette with human validation, other makeup categories, MaIA Beauty Advisor or an enterprise contract? Talk to us — B4A delivers complete projects on top of the same API.