# Contentful

Contentful is a headless content management system (CMS) that provides a content infrastructure for digital teams to power websites, apps, and devices. The Sling Contentful connector extracts data from the Contentful Content Delivery API (CDA), supporting content types, entries, assets, locales, and tags.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials are accepted:

**Secrets:**

* `access_token` **(required)** -> Your Contentful Content Delivery API access token

**Inputs:**

* `space_id` **(required)** -> Your Contentful Space ID
* `environment_id` *(optional, defaults to `master`)* -> The environment to query
* `anchor_date` *(optional, defaults to 1 year ago)* -> Starting date for first incremental sync (ISO 8601 format)

### Getting Your API Credentials

1. Log in to [Contentful](https://app.contentful.com)
2. Navigate to **Settings** → **API keys**
3. Click **Add API key** (or use an existing one)
4. Copy the **Space ID** and **Content Delivery API - access token**

{% hint style="warning" %}
**Important:** The Content Delivery API token provides read-only access to published content. Keep your token secure and never share it publicly.
{% endhint %}

### Using `sling conns`

Here are examples of setting a connection named `CONTENTFUL`. We must provide the `type=api` property:

{% code overflow="wrap" %}

```bash
sling conns set CONTENTFUL type=api spec=contentful secrets='{ access_token: your_cda_access_token }' inputs='{ space_id: your_space_id }'
```

{% endcode %}

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

{% code overflow="wrap" %}

```bash
export CONTENTFUL='{ type: api, spec: contentful, secrets: { access_token: "your_cda_access_token" }, inputs: { space_id: "your_space_id" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

```yaml
connections:
  CONTENTFUL:
    type: api
    spec: contentful
    secrets:
      access_token: "your_cda_access_token"
    inputs:
      space_id: "your_space_id"
      environment_id: "master"  # optional
```

## Replication

Here's an example replication configuration to sync Contentful data to a PostgreSQL database:

```yaml
source: CONTENTFUL
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: contentful.{stream_name}

streams:
  # sync all endpoints
  '*':
```

**Incremental sync for entries and assets:**

```yaml
source: CONTENTFUL
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: contentful.{stream_name}

streams:
  content_types:
  entries:
    mode: incremental
    primary_key: [id]
    update_key: updated_at
  assets:
    mode: incremental
    primary_key: [id]
    update_key: updated_at
  locales:
  tags:
```

## Endpoints

| Endpoint        | Description                                    | Incremental | Depends On |
| --------------- | ---------------------------------------------- | ----------- | ---------- |
| `content_types` | All content type definitions in the space      | No          | —          |
| `entries`       | All published entries across all content types | Yes         | —          |
| `assets`        | All published assets (images, files, media)    | Yes         | —          |
| `locales`       | All locales configured in the space            | No          | —          |
| `tags`          | All content tags in the space                  | No          | —          |

To discover available endpoints:

```bash
sling conns discover CONTENTFUL
```

### Endpoint Details

**`content_types`** — Returns all content type definitions including field schemas, display field configuration, and revision history. Useful for understanding the content model of your Contentful space.

**`entries`** — Returns all published entries across all content types with their fields, metadata, and content type association. Supports incremental sync via `sys.updatedAt` filtering, so subsequent runs only fetch entries modified since the last sync.

**`assets`** — Returns all published assets including file metadata (URL, dimensions, content type), title, and description. Supports incremental sync via `sys.updatedAt` filtering.

**`locales`** — Returns all locales configured in the space, including locale codes, fallback settings, and whether each locale is the default.

**`tags`** — Returns all content tags defined in the space, which can be used to organize and filter content.

## Incremental Sync

The `entries` and `assets` endpoints support incremental sync using the `sys.updatedAt` filter:

* **First run:** Fetches all records updated within the configured lookback window (default: 1 year, configurable via `anchor_date` input)
* **Subsequent runs:** Only fetches records updated after the last sync timestamp

All other endpoints (`content_types`, `locales`, `tags`) run in full-refresh mode since they typically contain small amounts of configuration data.

### Configuring the Lookback Window

You can customize how far back the first incremental sync reaches by setting the `anchor_date` input:

```yaml
connections:
  CONTENTFUL:
    type: api
    spec: contentful
    secrets:
      access_token: "your_cda_access_token"
    inputs:
      space_id: "your_space_id"
      anchor_date: "2024-01-01T00:00:00Z"  # start from Jan 1, 2024
```

## Rate Limiting

The Contentful Content Delivery API enforces rate limits:

* **Free plan:** 78 requests per second
* **Paid plans:** Higher limits

The connector automatically:

* Uses rate limiting (10 requests/second with concurrency of 3)
* Retries with exponential backoff on 429 (rate limit) responses
* Allows up to 5 retry attempts
* Continues gracefully on 404 responses

## Common Use Cases

### Sync All Contentful Data

```yaml
source: CONTENTFUL
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: contentful.{stream_name}

streams:
  '*':
```

### Sync Entries and Assets Incrementally

```yaml
source: CONTENTFUL
target: MY_POSTGRES

defaults:
  object: contentful.{stream_name}

streams:
  content_types:
    mode: full-refresh
  entries:
    mode: incremental
    primary_key: [id]
    update_key: updated_at
  assets:
    mode: incremental
    primary_key: [id]
    update_key: updated_at
```

### Extract Content Model Only

```yaml
source: CONTENTFUL
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: contentful.{stream_name}

streams:
  content_types:
  locales:
  tags:
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.slingdata.io/connections/api-connections/contentful.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
