Server SDK
@ghayma/sdk is the server half of the Ghayma runtime SDK. It holds a
project API key, administers your auth app’s end users,
reads and writes storage objects, and hands you database connection details.
This entry holds a secret, so it belongs in server code only. For end-user authentication in the browser (login, register, profile), use the Client SDK, which authenticates with your app slug alone.
Installation
npm install @ghayma/sdkZero runtime dependencies — the SDK uses native fetch.
Quick Start
import { Ghayma } from "@ghayma/sdk";
const ghayma = new Ghayma({ apiKey: process.env.GHAYMA_API_KEY });
// Upload a file
await ghayma.storage.upload("bucket-id", "photo.jpg", file);
// List an auth app's end-users
const { users } = await ghayma.auth.listUsers("my-app");
// Get database connection details
const conn = await ghayma.database.getConnection("db-id");With no arguments at all, new Ghayma() reads GHAYMA_API_KEY from the
environment:
const ghayma = new Ghayma();On a connected site there is nothing to set. A site connected to a storage
bucket or a database is handed a
managed GHAYMA_API_KEY in its container on
every deploy, so the zero-argument constructor works as it stands. Set the
variable yourself — in the console, or with
ghayma env set GHAYMA_API_KEY=gsk_... — for auth-app user administration,
and for a server hosted outside Ghayma. Without a credential the constructor
throws.
Verifying an end-user’s JWT is not part of this SDK — do it locally against your auth app’s JWKS. See JWT Verification.
Configuration
const ghayma = new Ghayma({
apiKey: "gsk_...", // Default: GHAYMA_API_KEY
baseUrl: "https://api.ghayma.tech", // Default
timeout: 30000, // 30 seconds default
maxRetries: 2, // Retries on 5xx and network errors
});| Option | Type | Default | Description |
|---|---|---|---|
apiKey | string? | GHAYMA_API_KEY | Project API key (gsk_…) from Project → Settings → API keys |
apiToken | string? | — | Deprecated. An account token (gh_…) still authenticates, and warns |
baseUrl | string? | https://api.ghayma.tech | API base URL. An explicit value wins over the environment |
timeout | number? | 30000 | Request timeout in milliseconds |
maxRetries | number? | 2 | Retries on 5xx and network errors, with backoff |
The credential is resolved in that order — apiKey, then apiToken, then
GHAYMA_API_KEY. Passing an account token logs one warning per process:
@ghayma/sdk: you are using an account token. It acts as you across every project;
switch to a project API key (gsk_…) from Project → Settings → API keys.An account token acts as you across every project you can reach; a project key reaches one project’s application routes. See Account tokens vs project keys.
Environment Variables
| Variable | Purpose |
|---|---|
GHAYMA_API_KEY | The project API key the zero-argument constructor reads. Derived for a site connected to a bucket or a database |
GHAYMA_API_URL | Base URL override. An explicit baseUrl still wins |
GHAYMA_API_KEY=gsk_your_project_api_keyThat file is for local development. Deployed on Ghayma, a site connected to a
storage bucket or a database has GHAYMA_API_KEY already — see
Managed keys.
Deployed on Ghayma? Point the SDK at the internal API URL to avoid connection timeouts — the SDK reads the variable itself, so there is nothing to pass in code:
ghayma env set GHAYMA_API_URL=http://paas-api.paas-system.svc.cluster.local:8080See the Networking Guide for details.
Tree-Shakeable Imports
Import only the modules you need to reduce bundle size:
// Full SDK
import { Ghayma } from "@ghayma/sdk";
// Individual modules
import { StorageClient } from "@ghayma/sdk/storage";
import { AuthClient } from "@ghayma/sdk/auth";
import { DatabaseClient } from "@ghayma/sdk/database";What moved out in 1.1.0
Everything that creates, destroys or reconfigures infrastructure left the SDK.
Nothing about the backend changed — those are still the same REST endpoints,
they are simply not part of an app’s runtime surface. Each removed method has a
home in the console or the ghayma CLI:
| Removed | Where it lives now |
|---|---|
auth.createApp() | ghayma auth create, or the console’s Auth page |
auth.updateApp() | ghayma auth config, or the console’s Auth page |
auth.deleteApp() | ghayma auth delete, or the console’s Auth page |
auth.rotateKeys() | ghayma auth rotate-keys, or the console’s Auth page |
storage.createBucket() | ghayma storage create |
storage.deleteBucket() | ghayma storage delete |
storage.rotateCredentials() | ghayma connections rotate bucket, which gives one app a new key — a bucket’s own key is never handed out |
storage.makePublic() / storage.makePrivate() | ghayma storage expose / unexpose |
database.create() | ghayma db create |
database.delete() | ghayma db delete |
database.stop() / database.start() | ghayma db stop / db start |
database.rotateCredentials() | ghayma connections rotate database, which gives one app a new credential — a database’s own login is never handed out |
database.createBackup(), listBackups(), restoreBackup(), deleteBackup() | the console’s database Backups tab |
database.link() and database.unlink() went earlier, in 0.6.0: a managed
database belongs to one project for its whole life, chosen at creation.
Error Handling
All methods throw GhaymaError on failure:
import { GhaymaError } from "@ghayma/sdk";
try {
await ghayma.storage.upload("bucket-id", "file.txt", blob);
} catch (err) {
if (err instanceof GhaymaError) {
console.error(err.message); // "Bucket not found"
console.error(err.status); // 404
console.error(err.code); // "HTTP_404"
}
}With a project API key, two statuses are worth handling on their own: 404 for
a resource in another project, and 403 for a route the key may not use. See
what a key can reach.
Compatibility
The SDK works in any JavaScript runtime with native fetch:
- Node.js 18+
- Deno
- Bun
- Cloudflare Workers
Browsers run the client entry and presigned-URL uploads — never this one, which carries the key.