Docs

Authentication

Last updated: 2026-10-024 min read

Every request is authenticated with an API key. Send it as a Bearer token:

Authorization: Bearer gsk_live_xxx

If a Bearer token is awkward in your stack, the x-api-key: gsk_live_xxx header is accepted too. Without a key every request gets 401 with title: invalid_key.

Key format

gsk_live_<id>_<secret> or gsk_test_<id>_<secret>. A gsk_live key does real work and is charged. A gsk_test key works in the sandbox: tools are simulated and nothing is charged; listings, leads and other real data cannot be changed with it. Choose the key type when you create the key.

The secret is shown once, at creation. GREM stores only its hash, so a lost key cannot be recovered - create a new one and revoke the old one.

Managing keys

In the cabinet, API → Keys:

  • Create a key with a label. Advanced settings let you pick scopes and an expiry in days. Without a choice the key gets every scope.
  • Rotate - issue a new secret; the old one keeps working for 24 hours so you can swap it in your integration.
  • Revoke - the key stops working immediately and for good.

The key status is shown in the list: active - works; suspended - API access paused by an administrator (reversible, the key is not destroyed); revoked - revoked. A key with an expiry is no longer accepted once it passes (401).

Agency keys

An agency owner or manager can issue a key on behalf of the agency: switch the key list to the agency scope. Such a key:

  • sees the agency's listings and leads, not personal ones;
  • can take leads from the agency's shared pool and return them (Leads);
  • can move listings into the agency and assign an agent (Listings).

A key can be bound to one agent - it then acts as that agent, with that agent's permissions.

Scopes

Every key carries a set of scopes. A call without the required scope returns 403 with title: forbidden_scope. The scope an operation needs is given in its description in /openapi.json (field x-required-scope).

ScopeGrants
pingkey check (GET /ping itself works without it)
tools:valuationexpress valuation and the full valuation report
tools:rentrent estimate
tools:reviewchecking someone else's valuation report
tools:contentgenthe listing content pack
tools:textlisting texts
tools:videovideo from photos, the music and closing-phrase lists
tools:avataravatar videos and the avatar list
tools:photophoto enhancement
tools:floorplanfloor plan cleanup
tools:sitegenlisting landing page
tools:pdfPDF presentation
tools:flyerpersonal broker flyer
tools:draftlisting draft from documents or a website
tools:chatAI assistant chat
tools:artifactsdownloading generated files
objects:writecreating, editing and deleting your listings
leads:readreading leads and Swipe Match leads
leads:writecreating and editing leads, Swipe Match events
media:writeimage uploads
webhooksmanaging event subscriptions

Without any scope you can call GET /ping, GET /me, GET /dictionaries, GET /objects, GET /voices, GET /tools/status and GET /works.

Which key is this

curl https://developers.grem.capital/api/v1/me \
  -H "Authorization: Bearer gsk_live_xxx"

GET /me returns the key id and prefix, who it belongs to (subjectType: user or agency, subjectId, and agencyMemberId for an agent key), the granted scopes, the rate limits that apply to this very key (rateLimit.rpm per minute and rateLimit.rpd per day) and the expiry. The secret is never returned. Free.

Security

Never put a key in browser code, a mobile app, a public repository or a URL. Anyone holding the key spends your account's money. If a key leaks, revoke it at once.

  • Keep keys in server-side environment variables or a secrets manager.
  • Use a separate key per integration with only the scopes it needs - revoking one does not affect the others.
  • Rotate keys on a schedule.
  • Requests are accepted over HTTPS only.

Was this article helpful?