# Get Context API

Get Context API provides a functionality for retrieving a context object from a backend API endpoint using an HTTP GET request. The response is a JSON object containing multiple namespaces, each with its own set of context keys and values. These keys are stored as [Context Keys](https://docs.applicaster.com/integrations/pipes2-endpoint-implementation-guide#using-context-parameters).

This API could be used to pull location information, specific app parameters (for example determine which environment to use staging or production), etc.

This API will be consumed by the Context Setter Plugin.

## Request

The Get Context API accepts an HTTP GET request to the endpoint `/get-context` (for example).

Example request:

```
GET /get-context HTTP/1.1
Host: example.com
```

### Configuration URLs

The Context Setter Plugin supports two types of URL configurations:

1. **Remote URL** (initial): Fetched during app initialization. Only supports `storage_keys` for temporary session data.
2. **Runtime URL**: Fetched after app initialization (e.g., after authentication). Supports both `storage_keys` and `persistent_keys`.

Both URLs can be configured with additional parameters through [Endpoints](/using-zapp/content/endpoints-and-context-keys).

Endpoints allow you to add context keys as query parameters, headers, or authentication tokens to URLs based on string matching. When the Context Setter Plugin makes an HTTP GET request to the configured URL, any matching endpoint configuration will automatically append the specified context keys to the request. This enables flexible context fetching based on different environments (development, staging, production) or user-specific parameters like access tokens.

## Response

If the backend API endpoint responds with an HTTP status code of 200, the Get Context API will return an HTTP status code of 200 along with the response body, which will be a JSON object with multiple namespaces and their corresponding context keys and values.

### Remote URL Response (Initial)

For the initial Remote URL, only `storage_keys` are supported:

```json
{
  "version": 1,
  "storage_keys": {
    "namespace1": {
      "contextKey1": "VALUE",
      "contextKey2": "VALUE"
    },
    "namespace2": {
      "contextKey1": "VALUE",
      "contextKey2": "VALUE"
    }
  }
}
```

### Runtime URL Response

For the Runtime URL, both `storage_keys` and `persistent_keys` are supported:

```json
{
  "version": 1,
  "storage_keys": {
    "namespace1": {
      "contextKey1": "VALUE",
      "contextKey2": "VALUE"
    }
  },
  "persistent_keys": {
    "content": {
      "namespace1": {
        "persistentKey1": "VALUE",
        "persistentKey2": "VALUE"
      }
    }
  }
}
```

These values will be stored as Context Keys.

### Storage Keys vs Persistent Keys

The response supports two types of key storage:

- **storage_keys**: Context keys that are stored in memory only and will be cleared when the app is restarted or when new context data is fetched. These are temporary context values. The structure is a flat object where each namespace contains key-value pairs. Available for both Remote URL and Runtime URL.

- **persistent_keys**: Context keys that are persisted to local storage and will survive app restarts. These keys remain available across sessions until explicitly cleared or overwritten by a new API call. The structure requires a `content` property containing the namespaces and their key-value pairs, and optionally a `scope` property for scoped storage. **Available only for Runtime URL configuration.**

#### Unscoped Persistent Keys

For unscoped persistent storage, use the `content` property without a `scope`:

```json
{
  "persistent_keys": {
    "content": {
      "namespace1": {
        "key1": "value1"
      }
    }
  }
}
```

#### Scoped Persistent Keys

For scoped persistent storage (e.g., user account data), include both `scope` and `content` properties. Currently supported scopes: `user_account`.

```json
{
  "persistent_keys": {
    "scope": "user_account",
    "content": {
      "namespace1": {
        "key1": "value1"
      }
    }
  }
}
```

Scoped keys are automatically managed and will be cleared when the associated scope is invalidated (e.g., on logout for `user_account` scope).

The keys are accessible as [Context Keys](https://docs.applicaster.com/integrations/pipes2-endpoint-implementation-guide#using-context-parameters) throughout the application.

## Usage Examples

### Example 1: Session-Only Data (Remote URL or Runtime URL)

Use `storage_keys` for temporary session data that should be cleared on app restart:

```json
{
  "version": 1,
  "storage_keys": {
    "session": {
      "sessionId": "abc123xyz",
      "temporaryToken": "temp_token_12345"
    }
  }
}
```

### Example 2: Persistent User Preferences (Runtime URL only)

Use `persistent_keys` for data that should persist across app sessions:

```json
{
  "version": 1,
  "persistent_keys": {
    "content": {
      "userPreferences": {
        "selectedRegion": "US",
        "contentLanguage": "en"
      }
    }
  }
}
```

### Example 3: Combined Storage (Runtime URL only)

Use both `storage_keys` and `persistent_keys` together:

```json
{
  "version": 1,
  "storage_keys": {
    "session": {
      "sessionId": "abc123xyz"
    }
  },
  "persistent_keys": {
    "content": {
      "user": {
        "userId": "user_12345",
        "environment": "production"
      }
    }
  }
}
```

In this example, the `sessionId` will be cleared on app restart, but `userId` and `environment` will persist across sessions.

### Example 4: Scoped Persistent Keys (Runtime URL only)

Use scoped `persistent_keys` for user-specific data that should be automatically cleared on logout:

```json
{
  "version": 1,
  "persistent_keys": {
    "scope": "user_account",
    "content": {
      "profile": {
        "userId": "user_12345",
        "userName": "john_doe",
        "email": "john@example.com"
      }
    }
  }
}
```

When using `scope: "user_account"`, the keys in `content` will be associated with the user account scope and automatically managed by the login flow. These keys will be purged when the user logs out.

## Advanced Use Case: Dynamic User Data with Endpoint Tags

You can combine the Context Setter Plugin's runtime URL parameter with the `observe_storage` endpoint tag to automatically fetch and update user account data based on authentication state changes.

### How It Works

This approach uses two features together:

1. **Runtime URL Parameter**: Configure an additional URL on the Context Setter Plugin that will be fetched after the application loads (and access tokens are refreshed)
2. **Endpoint Tag `observe_storage`**: Add this tag to the endpoint to make it observe all context keys it uses and automatically reload when any of those keys are updated

### Configuration Steps

1. **Configure the Runtime URL**: Set up your Context Setter Plugin with a URL endpoint that returns user account data (similar to the regular startup Remote URL format shown in the examples above)

2. **Create an Endpoint with observe_storage tag**: 
   - Create an endpoint in Zapp that matches your runtime URL
   - Add necessary context keys (like access tokens) that will be injected into the request
   - Add the `observe_storage` tag to the endpoint configuration

3. **Handle Authentication State Changes**: The endpoint will automatically reload when observed context keys change (e.g., when a user logs in, logs out, or modifies their profile)

### Example Scenario

When a user logs in:
- Access token is stored as a context key
- The `observe_storage` tag detects the token change
- The Context Setter Plugin automatically re-fetches the runtime URL with the new token
- User account data is populated in storage

When a user logs out:
- Access token is cleared from context keys
- The `observe_storage` tag detects the token removal
- The runtime URL is fetched again (without a token)
- Your backend should return the same keys with `null` values to purge the user data from storage

Example response for logged-out state:

```json
{
  "version": 1,
  "persistent_keys": {
    "scope": "user_account",
    "content": {
      "user": {
        "userId": null,
        "userName": null,
        "email": null
      }
    }
  }
}
```

:::tip
This pattern works with feeds on screens, the Remote Context Setter Plugin, and Storefront. You can also use it to build features like dynamic tabs or filters by combining the `observe_storage` tag with actions that write to storage or screen state.
:::

:::note
Some reserved namespace names automatically purge data from local storage on logout, but it's recommended to explicitly return `null` values for all user-related keys to ensure clean state management.
:::

## Errors

In case of an error, the backend should return the following error:

- **status** (number): the HTTP status code of the error response.
- **message** (string): a human-readable error message.

Example error message:

```json
{
  "status": 400,
  "message": "Invalid query parameter."
}
```

:::info
The provided context keys will override any existing context keys currently stored in the app. For `storage_keys`, this happens each time the API is called (both Remote URL and Runtime URL). For `persistent_keys` (Runtime URL only), the values are overwritten in persistent storage and will remain until the next update or until the app data is cleared.
:::
