API FlavosoRéférence de l'APIOAuth

OAuth

Les points de terminaison de l'authentification : autorisation dans le navigateur, échange de jetons, révocation et métadonnées. L'autorisation est une page sous https://app.flavoso.com/oauth/authorize, car c'est là que le propriétaire s'identifie ; l'échange de jetons, la révocation et les métadonnées se trouvent sur https://api.flavoso.com, en dehors de /v1. Le déroulement pas à pas est décrit sous Authentification.

Points de terminaison

Ask an owner to connect your app

get/oauth/authorize

Droit:
sans authentification

Opens in the browser on https://app.flavoso.com, not from your server. The user signs in (with a second factor if they set one up), picks a restaurant they own, reviews your app and its scopes and presses Connect or Cancel.

Afterwards Flavoso redirects to redirect_uri with code, state and iss (RFC 9207), or with error, error_description, state and iss. iss is the issuer https://api.flavoso.com, not the host of this page. With an unknown client_id, an unregistered redirect_uri or duplicate parameters, Flavoso shows an error page and does not redirect. Other errors go back to redirect_uri only for an approved app or when you are signed in as its developer; a rejected or suspended app never gets a redirect. A confidential app whose redirect_uri is a loopback address or a custom scheme can only connect your own test restaurant; the screen then offers only that one. The address redirects to the language of the browser.

error on the redirect is one of: access_denied (the user pressed Cancel, or may not connect this app to the chosen restaurant, for example because they do not own it or because a confidential app with a loopback or custom-scheme redirect_uri only connects your test restaurant), invalid_request (a parameter is missing or invalid, such as state or the PKCE parameters), invalid_scope, unsupported_response_type and server_error (the connection could not be saved).

Paramètres

NomEmplacementDescription
response_typestringobligatoirequeryAlways code."code"
client_idstringobligatoirequeryYour app's client ID (flv_app_…).
redirect_uristringobligatoirequeryOne of your app's registered redirect URIs, exactly as registered (loopback addresses with any port). A confidential app connects real restaurants only through an https redirect URI.max 300 chars
scopestringquerySpace-separated scopes, only from your app's scopes. Without it, all of your app's scopes are requested.
statestringobligatoirequeryA random value you keep and compare after the redirect.max 500 chars
code_challengestringobligatoirequeryBASE64URL(SHA-256(code_verifier)) without padding. Keep the code_verifier (43 to 128 characters) for the exchange.43 chars
code_challenge_methodstringobligatoirequeryAlways S256."S256"
Requête
# Authorization request (one line, wrapped here for reading)
https://app.flavoso.com/oauth/authorize?response_type=code
  &client_id=flv_app_...
  &redirect_uri=https%3A%2F%2Fexample.com%2Fflavoso%2Fcallback
  &scope=orders%3Awrite%20menu%3Awrite%20store%3Awrite
  &state=STATE
  &code_challenge=CODE_CHALLENGE
  &code_challenge_method=S256

# Connected: back at your redirect_uri
https://example.com/flavoso/callback?code=AUTHORIZATION_CODE&state=STATE&iss=https%3A%2F%2Fapi.flavoso.com

# Not connected, for example after "Cancel"
https://example.com/flavoso/callback?error=access_denied&error_description=...&state=STATE&iss=https%3A%2F%2Fapi.flavoso.com

Exchange a code or a refresh token for tokens

post/oauth/token

Droit:
sans authentification

Form-encoded body (application/x-www-form-urlencoded), at most 8 KB, no repeated parameters. Confidential clients authenticate with HTTP Basic (client_id:client_secret) or with client_id and client_secret in the body; public clients send client_id only. Every response carries Cache-Control: no-store.

authorization_code: the code is valid for 10 minutes and once; redirect_uri must be the one used for the authorization, code_verifier must match the code_challenge. Redeeming a code twice revokes everything issued with it.

refresh_token: returns a new access token and a NEW refresh token; store the new one. If the response got lost on the way, presenting the previous refresh token again within 60 seconds returns a fresh pair, but only while the refresh token from the lost response is still unused; the pair from the lost response is revoked. In every other case, presenting a used refresh token revokes the whole family. Optional scope narrows the new access token only. A suspended app gets unauthorized_client; its connections and tokens stay, so keep them and try again later.

Corpsapplication/x-www-form-urlencoded

  • grant_typestringobligatoire

    What is exchanged.

    Valeurs:"authorization_code""refresh_token"

  • codestring

    The authorization code (authorization_code only).

  • redirect_uristring

    The same redirect URI as in the authorization request (authorization_code only).

  • code_verifierstring

    The PKCE verifier behind the code_challenge (authorization_code only).

  • refresh_tokenstring

    The refresh token (refresh_token only).

  • scopestring

    Narrows the new access token to fewer scopes (refresh_token only).

  • client_idstring

    Your client ID, unless sent via HTTP Basic.

  • client_secretstring

    Confidential clients only, unless sent via HTTP Basic.

Réponse200

The tokens of one connection.

  • access_tokenstring

    flv_at_…, valid for expires_in seconds.

  • token_typestring

    Always Bearer.

  • expires_ininteger

    Lifetime of the access token in seconds: 3600.

  • refresh_tokenstring

    flv_rt_…, valid for 180 days from its last use, rotated on every use.

  • scopestring

    The granted scopes, space-separated.

  • connection_idstring (uuid)

    The connection these tokens belong to.

  • tenantobject

    The restaurant.

    Champs contenus (3)
    • idstring (uuid)

      The restaurant's id.

    • namestring

      Its name.

    • slugstring

      Part of the address of its ordering page.

Erreurs

  • 400invalid_request, invalid_grant, unauthorized_client, unsupported_grant_type or invalid_scope, as { error, error_description } (RFC 6749).
  • 401invalid_client: client authentication failed. Comes with WWW-Authenticate.
  • 429temporarily_unavailable: too many requests. Wait Retry-After seconds.
  • 500server_error.

Tous les codes d'erreur

Requête
# Confidential client: HTTP Basic (or client_id and client_secret in the body)
curl https://api.flavoso.com/oauth/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code=AUTHORIZATION_CODE \
  --data-urlencode redirect_uri=https://example.com/flavoso/callback \
  -d code_verifier=$CODE_VERIFIER

# Public client (native or desktop app): client_id only, no secret
curl https://api.flavoso.com/oauth/token \
  -d grant_type=authorization_code \
  -d code=AUTHORIZATION_CODE \
  --data-urlencode redirect_uri=com.example.pos:/callback \
  -d code_verifier=$CODE_VERIFIER \
  -d client_id=$CLIENT_ID
Réponse
{
  "access_token": "flv_at_...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "flv_rt_...",
  "scope": "orders:write menu:write store:write reports:read",
  "connection_id": "4b3f7c1e-9a2d-4e8b-b5f6-0c1d2e3f4a5b",
  "tenant": {
    "id": "7d0e5b8a-3c41-4f2e-9a6b-1e2d3c4b5a69",
    "name": "Pizzeria Example",
    "slug": "pizzeria-example"
  }
}

Revoke a token

post/oauth/revoke

Droit:
sans authentification

RFC 7009. The client authenticates as at the token endpoint (HTTP Basic, or client_id and client_secret in the body; public clients send client_id only). Without token the answer is 400 invalid_request, without valid client authentication 401 invalid_client. After that it always answers 200 with an empty body, also for unknown tokens, so nobody learns which tokens exist. The kind of token is taken from its form (flv_at_…, flv_rt_…). A refresh token revokes its whole family, an access token only itself. The connection stays; to end it, call DELETE /connection.

Corpsapplication/x-www-form-urlencoded

  • tokenstringobligatoire

    The access or refresh token.

  • token_type_hintstring

    Optional; Flavoso recognises the kind from the token itself.

    Valeurs:"access_token""refresh_token"

  • client_idstring

    Your client ID, unless sent via HTTP Basic.

  • client_secretstring

    Confidential clients only, unless sent via HTTP Basic.

Réponse200

Empty body.

Erreurs

  • 400invalid_request: token is missing, or the body is malformed (wrong content type, repeated parameters, two authentication methods).
  • 401invalid_client: client authentication failed. Comes with WWW-Authenticate.
  • 429temporarily_unavailable: too many requests. Wait Retry-After seconds.

Tous les codes d'erreur

Requête
curl https://api.flavoso.com/oauth/revoke \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d token=$REFRESH_TOKEN

Authorization server metadata

get/.well-known/oauth-authorization-server

Droit:
sans authentification

RFC 8414. Endpoints, grant types, PKCE methods, client authentication methods and scopes, machine-readable. No authentication; readable from a browser.

Réponse200

The metadata.

  • issuerstring

    https://api.flavoso.com. Compare it with iss after the redirect.

  • authorization_endpointstring

    Where to send the browser.

  • token_endpointstring

    Where to exchange codes and refresh tokens.

  • revocation_endpointstring

    Where to revoke tokens.

  • grant_types_supportedstring[]

    authorization_code, refresh_token.

  • code_challenge_methods_supportedstring[]

    S256 only.

  • token_endpoint_auth_methods_supportedstring[]

    client_secret_basic, client_secret_post, none.

  • scopes_supportedstring[]

    Every scope an app can request.

  • authorization_response_iss_parameter_supportedboolean

    true: the redirect carries iss.

Requête
curl https://api.flavoso.com/.well-known/oauth-authorization-server
Réponse
{
  "issuer": "https://api.flavoso.com",
  "authorization_endpoint": "https://app.flavoso.com/oauth/authorize",
  "token_endpoint": "https://api.flavoso.com/oauth/token",
  "revocation_endpoint": "https://api.flavoso.com/oauth/revoke",
  "response_types_supported": [
    "code"
  ],
  "response_modes_supported": [
    "query"
  ],
  "grant_types_supported": [
    "authorization_code",
    "refresh_token"
  ],
  "code_challenge_methods_supported": [
    "S256"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post",
    "none"
  ],
  "revocation_endpoint_auth_methods_supported": [
    "client_secret_basic",
    "client_secret_post",
    "none"
  ],
  "scopes_supported": [
    "orders:read",
    "orders:write",
    "menu:read",
    "menu:write",
    "store:read",
    "store:write",
    "reservations:read",
    "reservations:write",
    "reports:read"
  ],
  "authorization_response_iss_parameter_supported": true,
  "ui_locales_supported": [
    "de",
    "en",
    "fr",
    "es",
    "it"
  ],
  "service_documentation": "https://docs.flavoso.com/en/api/authentication"
}

Une question reste ouverte ? Écrivez à support@flavoso.com en indiquant l'identifiant de X-Request-Id. Il nous permet de retrouver votre requête dans le journal.