claimSubdomain

Tenant admin (bearer) SIGNATURE+ callable

Claim a branded `*.fotowall.io` subdomain for your tenant. Write-once enforced.

METHOD POST
PATH /claimSubdomain
AUTH Tenant admin (bearer)

Atomic uniqueness transaction that writes the subdomain field on tenants/{tid}. Slug must match `^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$` (3-40 chars, lowercase alphanumeric + hyphen). A reserved-word list blocks ~120 technical / brand / profanity slugs. Once a slug is `active`, the tenant admin cannot change it — releaseSubdomain is the superadmin-only escape hatch. Soft errors (invalid / reserved / taken / already-claimed) return `{ ok: false, reason }` so the admin UI can render inline.

AUTH NOTE

Requires a Firebase Auth ID token with role=admin (or superadmin) custom claim. Tenant-scoped unless invoked by a superadmin with an explicit tenantId.

Request

FieldTypeRequiredDescription
slug string yes 3-40 chars, lowercase alphanumeric + hyphen. No leading or trailing hyphen.
tenantId string no Superadmin-only: claim on behalf of another tenant. Tenant admins MUST omit or pass their own tenantId.

EXAMPLE BODY

{
  "slug": "acme-gala"
}

Response

FieldTypeAlways presentDescription
ok boolean yes true on a successful (or idempotent) claim. false on a soft error.
idempotent boolean no Present and true when the caller re-claims the same slug they already own.
reason "invalid" | "reserved" | "taken" | "already-claimed" no Present when ok=false.

EXAMPLE BODY

{
  "ok": true
}

curl

curl -X POST https://us-central1-freedomgrc-photowall.cloudfunctions.net/claimSubdomain \
  -H "Authorization: Bearer <firebase-id-token>" \
  -H "Content-Type: application/json" \
  -d '{"data":{"slug":"acme-gala"}}'

JavaScript

We don't ship a first-party JS SDK yet (it's on the roadmap). For callable endpoints, the Firebase Functions SDK is the recommended path — it handles ID-token attachment and payload framing. Plain fetch works too.

import { getFunctions, httpsCallable } from 'firebase/functions';

const functions = getFunctions(app, 'us-central1');
const claim     = httpsCallable(functions, 'claimSubdomain');

const result = await claim({ slug: 'acme-gala' });
// On success:    result.data === { ok: true }
// Already owned: result.data === { ok: true, idempotent: true }
// Soft error:    result.data === { ok: false, reason: 'taken' }

Error cases

CodeWhen
unauthenticated No Firebase Auth ID token.
permission-denied Caller is not a tenant admin (or superadmin). Or admin tried to claim for a different tenant.
invalid-argument No target tenant resolvable from auth + input.
not-found tenantId references a non-existent tenant.
internal Uniqueness transaction failed (typically Firestore contention).

Need a different shape?

The API surface is small. Tell us what you need and we'll work backward from your integration.

Request an endpoint Back to API index