requestPhotoDeletion

Public (no auth) callable

Guest-callable soft-delete for a single photo, gated on the uploader's session ID.

METHOD POST
PATH /requestPhotoDeletion
AUTH Public (no auth)

Soft-deletes a photo (status="deleted") on behalf of the guest who uploaded it. No Firebase Auth identity required — the integrity check is a stable sessionId the browser generated at upload time. Rate-limited to 30 requests per IP per hour. Cleaned up via cleanup-deleted.mjs after the 90-day retention window.

AUTH NOTE

No authentication. Integrity is gated on a domain-specific check (uploader sessionId, gallery password, etc.). Rate-limited per IP.

Request

FieldTypeRequiredDescription
eventId string yes Your Fotowall event ID. No slashes, periods, or whitespace.
photoId string yes The photo doc ID inside events/{eventId}/photos.
sessionId string yes The uploader's session ID (min 8, max 128 chars). Must match the value stamped on the photo doc if present.

EXAMPLE BODY

{
  "eventId": "spring-gala-2026",
  "photoId": "ph_8a92",
  "sessionId": "sess_4f7d2b8c9e1a3f6b"
}

Response

FieldTypeAlways presentDescription
ok boolean yes Always true on success. If the photo was already deleted, returns ok=true (idempotent).

EXAMPLE BODY

{
  "ok": true
}

curl

curl -X POST https://us-central1-freedomgrc-photowall.cloudfunctions.net/requestPhotoDeletion \
  -H "Content-Type: application/json" \
  -d '{
    "data": {
      "eventId":   "spring-gala-2026",
      "photoId":   "ph_8a92",
      "sessionId": "sess_4f7d2b8c9e1a3f6b"
    }
  }'

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.

// Callable Cloud Functions wrap their payload under { data: ... }
// when invoked over HTTPS directly.
const response = await fetch(
  'https://us-central1-freedomgrc-photowall.cloudfunctions.net/requestPhotoDeletion',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      data: {
        eventId:   'spring-gala-2026',
        photoId:   'ph_8a92',
        sessionId: 'sess_4f7d2b8c9e1a3f6b',
      },
    }),
  },
);
const { result } = await response.json();
// result === { ok: true }

Error cases

CodeWhen
invalid-argument eventId, photoId, or sessionId failed validation (length, regex, presence).
not-found No photo at events/{eventId}/photos/{photoId}.
permission-denied sessionId did not match the uploaderSessionId stamped on the photo.
resource-exhausted IP exceeded 30 calls/hour rate limit.
internal Firestore read/write failed. Sentry-reported, safe to retry.

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