> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryrollup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript API

> Every function and type in the expo-rollup module, as it appears in JavaScript and TypeScript.

The API of the `expo-rollup` module. [Expo and React Native](/platforms/expo) explains how to install it. Each function wraps a call of the Swift SDK, and each value has the fields of its [Swift type](/reference/overview), in the shapes below. The package ships these TypeScript types.

```ts theme={null}
import * as Rollup from 'expo-rollup';
```

## Setup

### configure

```ts theme={null}
function configure(publishableKey: string, options?: IndexOptionsInput): Promise<void>
```

Sets up the SDK with your app's publishable key and what to index. Options you leave out keep the SDK's defaults: the last three months, growing, of photos, screenshots and videos. Call it once when your app starts. Calling it again changes the options, and the index follows them.

Rejects with `missingRequirement` when the app lacks something the SDK needs, and with `simulatorUnsupported` in the iOS Simulator.

### requestPhotoAccess

```ts theme={null}
function requestPhotoAccess(): Promise<PhotoAccess>
```

Shows the system Photos prompt (once) and returns the person's answer. Call it right after the person chooses to turn the feature on: a grant starts the first index, which continues in the background.

### startIndexing

```ts theme={null}
function startIndexing(): Promise<void>
```

Starts indexing, or lets it continue in the background. Call it from a user action, such as a button press.

### getIndexOptions

```ts theme={null}
function getIndexOptions(): Promise<IndexOptions>
```

The index options in effect.

### reset

```ts theme={null}
function reset(): Promise<void>
```

Deletes everything the SDK keeps: the index, downloaded models and places, queued reports, and this device's record on Rollup's server. Indexing starts again from scratch the next time it starts.

## Indexing state

### useIndexingState

```ts theme={null}
function useIndexingState(): IndexingState | null
```

A React hook that keeps the indexing state current. It is `null` until the first state arrives, and always `null` where Rollup is not available.

### getIndexingState

```ts theme={null}
function getIndexingState(): Promise<IndexingState>
```

Where indexing is now.

### addIndexingStateListener

```ts theme={null}
function addIndexingStateListener(listener: (state: IndexingState) => void): { remove(): void }
```

Calls `listener` with the current state and every change after it, until you call `remove()`.

### isSearchable

```ts theme={null}
function isSearchable(state: IndexingState | null | undefined): boolean
```

Whether search, query and profile have an index to read: the state is `ready`, or `indexing` with `searchable` true.

## Search, query and profile

### search

```ts theme={null}
function search(text: string): Promise<SearchResults>
```

Searches the index on the iPhone: dates, places, media and what photos show or say. Results come most relevant first. See [Search](/guides/search).

### query

```ts theme={null}
function query(question: string): Promise<Answer>
```

Answers a question about the person's life from the index. The model runs on Rollup's server; its tools run on the iPhone, and only their text results leave it. Tell the person and get their permission first. See [Query](/guides/query) and [Privacy](/guides/privacy).

### profile

```ts theme={null}
function profile<T = { [key: string]: JSONValue }>(schema: object): Promise<Profile<T>>
```

Fills a JSON Schema (an object schema) about the person from the index: the schema's shape exactly, `null` where their life does not say, with the photos behind each filled field. Pass the schema as an object. Same permission as `query`. See [Profile](/guides/profile).

## Availability

```ts theme={null}
const isAvailable: boolean
const sdkVersion: string | null
```

`isAvailable` is true on iOS with the native module linked. Elsewhere it is false, `sdkVersion` is `null`, and every call rejects with `unsupportedPlatform`.

## Helpers

```ts theme={null}
const span: {
  days(value: number): Span;
  weeks(value: number): Span;
  months(value: number): Span;
  years(value: number): Span;
};

const indexWindow: {
  growing(from: Span): IndexWindow;
  sliding(recent: Span): IndexWindow;
};
```

`indexWindow.growing` reaches back `from` and keeps adding new photos; nothing ages out. `indexWindow.sliding` keeps only the most recent span, and removes older photos as time passes.

```ts theme={null}
await Rollup.configure('rk_live_...', { window: Rollup.indexWindow.sliding(Rollup.span.weeks(6)) });
```

## Types

Enums are objects tagged by `type`. Dates are ISO 8601 strings.

### IndexingState

```ts theme={null}
type IndexingState =
  | { type: 'notConfigured' }
  | { type: 'needsPhotoAccess' }
  | { type: 'downloadingAssets'; fraction: number }
  | { type: 'indexing'; indexed: number; total: number; searchable: boolean }
  | { type: 'ready'; photos: number; updatedAt: string }
  | { type: 'failed'; error: RollupErrorBody };
```

`searchable` means search, query and profile already work on the photos indexed so far.

### PhotoAccess

```ts theme={null}
type PhotoAccess = 'authorized' | 'limited' | 'denied' | 'restricted' | 'notDetermined';
```

### IndexOptionsInput and IndexOptions

`configure` takes the fields to change; every field you leave out keeps the SDK's default. `getIndexOptions` returns every field. See [Index options](/guides/index-options) for what each one does.

```ts theme={null}
type IndexOptionsInput = {
  window?: IndexWindow;
  mediaTypes?: MediaType[];
  focus?: Focus;
  places?: boolean;
  screenshotEntities?: boolean;
  allowsCellular?: boolean;
  updatesAutomatically?: boolean;
  maxPhotos?: number | null;
  backgroundProgress?: { title?: string; subtitle?: string };
};

type IndexOptions = {
  window: IndexWindow;
  mediaTypes: MediaType[];
  focus: Focus;
  places: boolean;
  screenshotEntities: boolean;
  allowsCellular: boolean;
  updatesAutomatically: boolean;
  maxPhotos?: number;
  backgroundProgress: { title: string; subtitle?: string };
};

type IndexWindow = { type: 'growing'; span: Span } | { type: 'sliding'; span: Span };
type Span = { unit: 'days' | 'weeks' | 'months' | 'years'; value: number };
type MediaType = 'photos' | 'screenshots' | 'videos';
type Focus = 'everything' | 'food';
```

### SearchResults

```ts theme={null}
type SearchResults = {
  query: string;
  results: SearchResult[];
  plan: SearchPlan;
  seconds: number;
  timings: Record<string, number>;
  coverage?: JSONValue;
};

type SearchResult = {
  id: string;                 // PhotoKit local identifier
  relevance?: number;
  matchedText?: string;
  date?: string;              // when it was taken
  timeZone?: { identifier: string };
  mediaType: 'photo' | 'video' | 'screenshot';
  isFavorite: boolean;
  location?: SearchLocation;
  labels: SearchLabel[];
  places: SearchPlace[];
  cuisines: string[];
  text?: string;
  screenshot?: SearchScreenshot;
  score?: number;
  retrievalScore?: number;
  placeSimilarity?: number;
  matchReasons: string[];
  placeMatches?: JSONValue;
};

type SearchLocation = {
  neighborhood?: string;
  city?: string;
  metro?: string;
  country?: string;
  countryCode?: string;
  latitude?: number;
  longitude?: number;
};

type SearchLabel = { id: string; name: string; probability?: number; similarity?: number };
type SearchPlace = { name: string; category?: string; confidence: number };

type SearchScreenshot = {
  appKind: string;
  topic: string;
  action: string;
  confidence: Record<string, number>;
  sensitivity: string[];
  eventTime?: string;
  temporalRelation: string;
  entities: { id: number; type: string; value: string }[];
  entityStatus: string;
};

type SearchPlan = {
  operation: string;
  retrievalIntent: string;
  visualText: string;
  sort: string;
  details: JSONValue;
};
```

See [SearchResults](/reference/search-results) for what each field means.

### Answer

```ts theme={null}
type Answer = {
  text: string;
  assetIdentifiers: string[];  // the photos the answer rests on
  declined: boolean;           // the question was not about the person's own life
};
```

### Profile

```ts theme={null}
type Profile<T = { [key: string]: JSONValue }> = {
  json: T;                            // the schema's shape, null where their life does not say
  evidence: Record<string, string[]>; // photos behind each filled field, by JSON Pointer
  refused: Record<string, string>;    // fields the server would not fill, with the reason
};
```

`json` is a parsed object, not a string. Pass your own type to `profile<T>()` to type it. Keys of `evidence` are JSON Pointers, such as `/food/favorite_cuisine`.

### JSONValue

```ts theme={null}
type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue };
```

## Errors

Every call rejects with a `RollupError`:

```ts theme={null}
class RollupError extends Error {
  readonly code: RollupErrorCode;
  readonly serverCode?: string;   // the server's own code, such as 'rate_limited'
  readonly retryable?: boolean;   // whether the same call can succeed later unchanged
  readonly retryAfter?: number;   // seconds to wait before retrying, when the server said
  toJSON(): RollupErrorBody;
}

function isRollupError(error: unknown, code?: RollupErrorCode): error is RollupError;
```

`message` is for developers, not for the person. A `failed` indexing state carries the same fields as a plain object (`RollupErrorBody`).

```ts theme={null}
type RollupErrorBody = {
  code: RollupErrorCode;
  message: string;
  serverCode?: string;
  retryable?: boolean;
  retryAfter?: number;
};
```

```ts theme={null}
type RollupErrorCode =
  | 'simulatorUnsupported'
  | 'notConfigured'
  | 'missingRequirement'
  | 'photoAccessDenied'
  | 'noIndex'
  | 'assetsUnavailable'
  | 'network'
  | 'server'
  | 'indexing'
  | 'cancelled'
  | 'invalidSchema'
  | 'accessRevoked'
  | 'appPendingApproval'
  | 'quotaExceeded'
  | 'rateLimited'
  | 'appAttestFailed'
  | 'unknown'
  | 'unsupportedPlatform'   // not an iPhone: Android, the web, or the module is not linked
  | 'invalidOptions';       // index options the SDK can't read
```

Every code but the last two comes from the Swift SDK. See [RollupError](/reference/rollup-error) for what each one means and [Troubleshooting](/guides/troubleshooting) for what to do.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.