API keys and authentication
Connect your application securely, keep the key on your backend, and understand how access is issued, checked and revoked.
A Luntero API key identifies the integration making a data request. Send it in the Authorization header, and keep it available only to systems you control. You do not need a Clerk session, a browser login or an OAuth exchange to call the data API.
This guide explains the complete access path: obtaining a key, using it from your server, replacing it when necessary and diagnosing authentication failures.
Request a key
Contact Luntero to request access and describe what you want to build. API keys are currently issued and revoked by Luntero. There is no self-service key dashboard, subscription checkout or monthly quota system in this release.
Your Luntero website account and an API key serve different purposes. Signing in to the website does not automatically give an application permission to call the API. For a data request, the credential that matters is the Bearer key attached to that request.
Send the Bearer header
The header has one space between Bearer and the key. Send the actual key value without additional quotes inside the header.
GET /v1/listings?limit=5 HTTP/1.1
Host: api.luntero.com
Authorization: Bearer YOUR_API_KEYIn curl, the surrounding double quotes belong to the shell syntax; they are not part of the header value:
curl --fail-with-body --silent --show-error \
'https://api.luntero.com/v1/listings?limit=5' \
-H "Authorization: Bearer $LUNTERO_API_KEY"Use the HTTPS URL directly. HTTP redirects to HTTPS, but relying on a redirect for an authenticated request can complicate how a client forwards sensitive headers. Configure https://api.luntero.com as your API base URL from the start.
Keep keys out of URLs
The API does not accept a key in query parameters. Do not add api_key, token or a similar parameter to a request URL. URLs can end up in browser history, analytics and access logs.
Put the key on your backend
For a browser or mobile product, use this request path:
Your browser or mobile app
│
│ Your application's request
▼
Your backend
│
│ HTTPS + Authorization: Bearer …
▼
Luntero APIYour backend decides which searches a user may perform, constructs the upstream request and adds the key. Your client receives the data it needs without receiving the Luntero credential.
The same approach works for a server-rendered application, background worker or internal dashboard. A server-only environment variable or secret manager is an appropriate place to supply the key. A variable exposed to the public frontend build is not: changing its name does not stop the value from being included in the bundle.
A small server-side example
The important boundary is where this function runs. Keep it in server code and expose an application-specific route or action to your own client.
export async function searchRentals(locationId: string) {
const key = process.env.LUNTERO_API_KEY;
if (!key) throw new Error("Luntero API key is not configured.");
const url = new URL("https://api.luntero.com/v1/listings");
url.searchParams.set("location_id", locationId);
url.searchParams.set("limit", "20");
const response = await fetch(url, {
headers: { Authorization: `Bearer ${key}` },
signal: AbortSignal.timeout(10_000),
});
if (!response.ok) {
throw new Error(`Rental search failed with HTTP ${response.status}.`);
}
return response.json();
}Validate incoming parameters on your own route as well. A private upstream key should not turn your backend into an unrestricted proxy for arbitrary URLs or unlimited public requests.
Understand browser access
The hosted request playground at docs.luntero.com is allowed to call the API directly. Arbitrary browser origins are not currently enabled by the API's CORS configuration.
If curl or your backend can call an endpoint but a browser page cannot, inspect the browser's network panel for a CORS error. Do not try to solve it by putting the key into the URL or shipping the secret to another frontend origin. Use your backend for that integration.
CORS is a browser access rule. Your server-to-server client still needs a valid API key, even though it does not perform a browser preflight check.
Store and handle the secret
Treat a key like any other service credential. Supply it at runtime, restrict access to the deployment configuration and avoid logging outgoing Authorization headers. A useful diagnostic log contains an HTTP status and request ID; it does not need the credential that made the request.
Luntero stores a SHA-256 digest of a high-entropy key rather than its plaintext value. The key you receive is still the value your application must send, so keep your own copy in the appropriate secret storage. Do not expect the service to recover a lost plaintext key for you.
Before sharing a curl command, screenshot or network trace, remove the actual header value. Replace it with YOUR_API_KEY so someone can understand the request without receiving access to your integration.
Replace or revoke a key
If you need to replace a working key, arrange a replacement with Luntero, update your backend's secret and deploy the change. Verify a small authenticated request from the updated service, then ask for the old key to be revoked. This lets you confirm the new credential before removing the old one.
If a key has been exposed, request revocation promptly. A revoked key is rejected on the next request; editing a secret in your own hosting configuration does not revoke the original credential at Luntero.
Keys may also be disabled or issued with an expiry. A client should treat 401 as a signal to check its credential, rather than repeatedly retrying the same header.
Diagnose an authentication failure
A missing, malformed, expired, disabled or revoked key can return 401 unauthorized. The message does not need to reveal which part of a credential was wrong.
| Check | What to look for |
|---|---|
| Header construction | Exactly Authorization: Bearer …, with the full key and no extra quotes or newlines. |
| Runtime configuration | The server process making the request actually received the secret after deployment. |
| Request destination | The request is going directly to the HTTPS API hostname. |
| Credential state | The key has not been replaced, revoked, disabled or allowed to expire. |
| Browser behaviour | A CORS failure is separate from the API returning an HTTP 401 response. |
Repeated failed authentication attempts can themselves be rate limited. If you receive 429, stop and respect Retry-After instead of continuing to test credentials rapidly.
What does not need authentication?
The public GET /v1/ping endpoint is available without a key. The documentation and OpenAPI specification are also public. A successful ping is useful for connectivity checks, but it does not establish that your key is valid or that a data endpoint can serve a request.