Flares Cloud is not currently available to new customers. This documentation is kept for the projects already running on it, and stays accurate for them. What happened.

Flares Developer Docs

Handling requests

Methods, headers, query, JSON bodies, status codes, response limits.

One function, every path under it

A function owns its URL and everything below it. That is what lets one deployment be an application rather than a single endpoint:

https://cloud.flaresinc.com/run/YOUR_PROJECT/api            → path "/"
https://cloud.flaresinc.com/run/YOUR_PROJECT/api/users       → path "/users"
https://cloud.flaresinc.com/run/YOUR_PROJECT/api/users/123   → path "/users/123"

The path your code sees is the part below your function's own name — not the project id, not the function name. Rename the function and its routing still works.

return function (Request $request): Response {
    if (($p = $request->match('/users/{id}')) !== null) {
        return Response::json(['user' => $p['id']]);
    }

    if ($request->route() === 'POST /posts') {
        return Response::json(['created' => true], 201);
    }

    return Response::json(['error' => 'not_found'], 404);
};
On the requestWhat it gives you
$request->pathThe path below your function. / at its root.
$request->segments()['users', '123'] — the path split, empties dropped.
$request->segment(0)One segment by position, or null past the end.
$request->match('/users/{id}')Captured parameters, or null when it does not match. {rest*} takes everything left.
$request->route()"POST /posts" — method and path, for a match statement.
$request->functionYour function's own name, for building links back to itself.
Forty routes in one function cost exactly what one route costs: a request is a request. How billing works →

Methods

The gateway accepts GET, POST, PUT, PATCH and DELETE at the same endpoint; your handler decides:

return function (Request $request): Response {
    return match ($request->method) {
        'GET'    => Response::json(list_items()),
        'POST'   => Response::json(create_item($request->json() ?? []), 201),
        'DELETE' => Response::empty(),
        default  => Response::json(['error' => 'method_not_allowed'], 405),
    };
};

Input

$request->query('page', '1');            // ?page=2
$request->header('X-Signature');         // case-insensitive
$request->body;                          // raw, exactly as sent
$request->json();                        // decoded array, or null

Cookie, Authorization and X-Flares-User-Token are stripped before your code sees the headers: platform credentials never reach customer code. The verified identity arrives as $request->user() instead.

Output

return Response::json(['ok' => true], 200, ['X-My-Header' => 'value']);

You control the status and your own headers. The platform owns transport headers — Set-Cookie, Content-Length, Transfer-Encoding, Connection — and headers containing CR/LF are dropped, so a header cannot be injected through a value.

CORS

Responses carry Access-Control-Allow-Origin: * and allow the common methods and headers, so a browser on your own domain can call a function directly. Authorization is the token's job, not the origin's.

Request ids

Every response carries X-Flares-Request-Id. Log it client-side and you can find the exact invocation in Logs — it is also the id that guarantees an internal retry cannot double-bill you.

Errors

If your code throws or dies, the caller gets 500 with {"error":"function_error","request_id":"…"} — never your stack trace, which could carry paths or secrets. The full error and any output are in your logs.