Suchen

POST /api/v1/search durchsucht die Team-Bibliothek des API-Key-Inhabers. Der Endpoint benötigt den Scope search und akzeptiert ein JSON-Objekt. Alle Felder sind optional.

Request

FeldTypStandardBeschreibung
qstringkeinerNicht leere Freitextsuche. Ohne q erscheinen die neuesten Dateien zuerst.
modestringhybridhybrid, text oder vector; wird mit q verwendet.
filtersobject{}Strukturierte Filter wie unten beschrieben.
limitnumber50Ganze Zahl von 1 bis 100.
cursorstringkeinerOpaque Cursor der vorherigen Seite.

hybrid kombiniert BM25 Full-Text Search mit Semantic Similarity. text verwendet nur BM25, vector nur Semantic Search.

json
{
  "q": "Sonnenuntergang am Strand",
  "mode": "hybrid",
  "filters": {
    "media_type": { "image": "include" },
    "rating": { "3:4": "include", "3:5": "include" }
  },
  "limit": 25
}
bash
curl --fail-with-body \
  -X POST "$NEW_ARCHIVE_URL/api/v1/search" \
  -H "Authorization: Bearer $NEW_ARCHIVE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "q": "Sonnenuntergang am Strand",
    "mode": "hybrid",
    "filters": {"media_type": {"image": "include"}},
    "limit": 10
  }'

Response

json
{
  "items": [
    {
      "id": "0198c9a0-7d3e-7c41-b7a2-3f9d1c2e4a5b",
      "status": "ready",
      "original_name": "sunset.jpg",
      "mime_type": "image/jpeg",
      "size_bytes": 2481931,
      "width": 4000,
      "height": 3000,
      "taken_at": "2026-06-30T18:41:02.000Z",
      "created_at": "2026-07-11T09:12:44.201Z",
      "thumbnail_url": "https://storage.example/signed-thumbnail"
    }
  ],
  "next_cursor": "eyJvIjoyNX0"
}

Einträge verwenden dasselbe Schema wie GET /api/v1/files/:fileId. Fertige Dateien enthalten eine Signed URL für ein kleines Thumbnail. next_cursor fehlt, wenn es keine weitere Seite gibt.

Pagination

Sende next_cursor unverändert zurück und behalte Query, Mode, Filter und Limit bei. Cursor sind opaque und dürfen von Clients weder erzeugt noch dekodiert werden.

js
async function searchAll(request) {
  const items = []
  let cursor

  do {
    const response = await fetch(
      `${process.env.NEW_ARCHIVE_URL}/api/v1/search`,
      {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.NEW_ARCHIVE_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ ...request, cursor }),
      }
    )
    const page = await response.json()
    if (!response.ok)
      throw new Error(`${page.error.code}: ${page.error.message}`)
    items.push(...page.items)
    cursor = page.next_cursor
  } while (cursor)

  return items
}

Filterverhalten

Die meisten Filterkategorien sind Tri-State-Maps. Jeder Wert verweist auf include oder exclude; ein fehlender Wert ist neutral. include-Werte innerhalb einer Kategorie werden per OR verknüpft, aktive Kategorien per AND. exclude-Werte werden immer vom Ergebnis abgezogen.

json
{
  "filters": {
    "media_type": { "image": "include" },
    "date": { "2026-06": "include" },
    "camera_make": { "Canon": "exclude" }
  }
}

Dies wählt Bilder aus Juni 2026 aus, die nicht mit einer Canon aufgenommen wurden.

Filterreferenz

KategorieAkzeptierte Keys
date, import_dateYYYY, YYYY-MM oder YYYY-MM-DD.
media_typeimage, video, other.
orientationlandscape, portrait, square.
format1:1, 4:3, 3:2, 16:9, other.
isolow, medium, high oder eine exakte Ganzzahl wie 400.
focal_length, focal_length_35mmsuper-wide, wide-angle, normal, tele, super-tele oder exakte Millimeter als Ganzzahl.
aperturevery-wide, wide, medium, narrow, very-narrow oder eine exakte Blendenzahl wie 1.8.
shutter_speedvery-fast, fast, normal, slow, long oder exakte Sekunden wie 0.002.
resolutionsd, hd, fhd, 4k, 6k, 8k. Die lange Kante bestimmt den Bucket.
file_sizetiny, small, medium, large, xlarge, huge.
person_countnone, single, two, three, small-group, big-group, crowd.
lensExakte Objektivbezeichnung aus den Metadaten.
color_spacesrgb, display-p3, adobe-rgb, prophoto-rgb, uncalibrated.
bit_depthString wie 8, 10, 12, 14, 16 oder 32.
file_typeDateiendung in Kleinbuchstaben, etwa jpg, cr3 oder mp4.
camera_makeExakte Herstellerbezeichnung.
camera_modelHersteller:Modell, etwa Canon:EOS R5.
geographyhas_location oder no_location.
versionshas_versions (mehr als die Ursprungsversion) oder no_versions.
country, state, city, suburbStandort-IDs als Strings.
categoriesKategorie-IDs als Strings; ein Elternknoten schließt seinen Unterbaum ein.
labelsLabel-IDs als Strings.
collectionsSammlungs-UUIDs.
rating<criterionId>:<stars>, <criterionId>:unrated, avg:<stars>, any:unrated oder any:incomplete.
custom<fieldId>:<value>, <fieldId>:__has__ oder <fieldId>:__empty__.

File-Size-Buckets verwenden dezimale Bytes: tiny liegt unter 1 MB, small bei 1–10 MB, medium bei 10–50 MB, large bei 50–250 MB, xlarge bei 250 MB–1 GB und huge ab 1 GB.

avg:<stars> bucketet jede Datei nach dem gerundeten Mittel ihrer durchschnittlichen Bewertungen pro Kriterium. Es zählen nur System- und Team-Kriterien, für die die Datei Bewertungen hat; Bewertungen auf Collection-Kriterien fließen nicht in den Durchschnitt der API ein.

ID-basierte Werte stammen aus eigenen Datensätzen oder der App. API v1 bietet keine Endpoints für Facetten- oder Taxonomielisten.

Numerische Custom Fields

custom_ranges ist keine Tri-State-Map. Die Keys sind Custom-Field-IDs; eine der beiden Grenzen darf fehlen.

json
{
  "filters": {
    "custom_ranges": {
      "7": { "min": 10, "max": 500 }
    }
  }
}

Semantic Search steuern

Beschreibende Phrasen eignen sich gut für Semantic Search. Stelle einem einzelnen Wort - voran, um das Konzept auszuschließen, etwa Hund am Strand -Menschen.

Wenn q oder filters.similar_to gesetzt ist, legt filters.max_distance einen Threshold für die Cosine Distance von 0 bis 1 fest. Niedrigere Werte sind strenger, 1 deaktiviert den Threshold. Ohne Angabe gilt der Server-Default (0.55).

json
{
  "q": "goldene Stunde",
  "filters": { "max_distance": 0.4 }
}

Bildsuche

filters.similar_to nimmt die ID einer deiner Dateien und sortiert die Ergebnisse nach visueller Ähnlichkeit zu ihr: ähnlichste zuerst, die Datei selbst ausgenommen, alle anderen Filter grenzen die sortierte Menge ein. Ist similar_to gesetzt, werden q und mode ignoriert. Eine gelöschte Datei oder eine ohne Bild-Embedding (Videos und Dokumente bekommen keins) liefert eine leere Liste.

json
{
  "filters": {
    "similar_to": "019b1a2c-3d4e-7f80-9a1b-2c3d4e5f6a7b",
    "labels": { "12": "include" }
  }
}