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

# Manifest schema reference

## Introduction

An Ampersand manifest (`amp.yaml`) is a YAML file that defines how your application integrates with various SaaS platforms through the Ampersand integration platform.

This page provides a comprehensive reference for the schema of this file, including detailed field descriptions and best practices.

<Tip>
  **VSCode Extension for amp.yaml**

  Install the [Ampersand Schema Validator](https://marketplace.visualstudio.com/items?itemName=amp-labs.ampersand-schema-validator) extension for Visual Studio Code to get:

  * Real-time validation and error detection
  * Auto-completion for all manifest fields
  * Hover documentation with examples
  * Quick fixes for common issues
  * Template generation for various providers

  This extension helps you write valid `amp.yaml` files faster and catch errors before deployment.
</Tip>

## OpenAPI spec

The OpenAPI spec for the manifest [is available on GitHub](https://github.com/amp-labs/openapi/blob/main/manifest/manifest.yaml).

## Top-level structure

The Ampersand manifest starts with a top-level structure that specifies the schema version and a list of integrations:

```yaml theme={null}
specVersion: 1.0.0
integrations:
  - name: integration1
    provider: provider1
    # ... integration 1 configuration
  - name: integration2
    provider: provider2
    # ... integration 2 configuration
```

| Field          | Type   | Required | Description                                                                                                                                 |
| -------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `specVersion`  | String | Yes      | The version of the manifest specification. Format: `MAJOR.MINOR.PATCH`. Currently only `1.0.0` is supported.                                |
| `integrations` | Array  | Yes      | An array of [integration configurations](#integration-configuration). Each element defines a complete integration with a specific provider. |

<Note>
  Notes

  * Only one `specVersion` is allowed per manifest file.
  * The `integrations` array must contain at least one integration configuration.
  * Multiple integrations can reference the same provider with different configurations.
</Note>

## Integration definition

Each integration defines a connection to a specific provider (e.g., Salesforce, HubSpot). This section contains the basic metadata about the integration:

```yaml theme={null}
name: my-integration
displayName: My Integration
provider: salesforce
module: crm  # Optional: for providers with modules
read:
  ...
write:
  ...
proxy:
  ...
subscribe:
  ...
```

| Field         | Type   | Required | Description                                                                                                                                                                  |
| ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`        | String | Yes      | A unique identifier for this integration within your manifest. Use lowercase alphanumeric characters, hyphens and underscores only. Maximum length: 64 characters.           |
| `displayName` | String | No       | A human-readable name for this integration. Maximum length: 100 characters.                                                                                                  |
| `provider`    | String | Yes      | The provider/platform for this integration. Must be one of the [supported providers](/provider-guides/overview) (e.g., `salesforce`, `hubspot`, `intercom`). Case-sensitive. |
| `module`      | String | No       | Module within the provider (e.g., `crm` for HubSpot CRM). Only applicable for certain providers.                                                                             |
| `subscribe`   | Object | No       | The [subscribe definition](#subscribe-definition). See [Subscribe Actions](/subscribe-actions) for implementation details.                                                   |
| `read`        | Object | No       | The [read definition](#read-definition). See [Read Actions](/read-actions) for implementation details.                                                                       |
| `write`       | Object | No       | The [write definition](#write-definition). See [Write Actions](/write-actions) for implementation details.                                                                   |
| `proxy`       | Object | No       | The [proxy definition](#proxy-definition). See [Proxy Actions](/proxy-actions) for implementation details.                                                                   |

<Note>
  Naming Conventions

  * `name`: Use descriptive, unique names that identify the purpose of the integration. Examples: `salesforce-contacts-sync`, `hubspot-crm-integration`, `github-issues-tracker`.
  * `displayName`: Use proper capitalization and spacing for better readability in UIs. Examples: "Salesforce Contacts Sync", "HubSpot CRM Integration", "GitHub Issues Tracker".
</Note>

## Subscribe definition

The `subscribe` section defines how to subscribe to real-time create, update, and delete events from the provider. This section is optional - if your integration does not need real-time data, you can omit this section. Learn more in [Subscribe Actions](/subscribe-actions).

```yaml theme={null}
subscribe:
  objects:
    - objectName: account
      destination: accountWebhook
      inheritFieldsAndMapping: true
      createEvent:
        enabled: always
      updateEvent:
        enabled: always
        watchFieldsAuto: all  # Alternatively, use requiredWatchFields
      deleteEvent:
        enabled: always
```

| Field     | Type  | Required | Description                                                                                                                  |
| --------- | ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `objects` | Array | Yes      | An array of [objects to subscribe](#subscribe-object) to. Each element defines a specific object type to receive events for. |

<Note>
  Subscribe considerations

  * Check the specific [provider guide](/provider-guides/overview) to see which providers support subscribe actions. If subscribe actions isn't supported for a particular provider, you can still use read actions to get updated data every 10 minutes.
  * A `read` block must always be defined alongside a `subscribe` block. Each subscribed object that uses `createEvent`, `updateEvent`, or `deleteEvent` must also have a matching object entry in the `read` block (with the same `objectName`) and set `inheritFieldsAndMapping: true`. Objects that only use `otherEvents` do not need their own entry in the `read` block.
  * Only one of `requiredWatchFields` or `watchFieldsAuto` should be provided for update events.
  * See [Subscribe Actions documentation](/subscribe-actions) for detailed implementation guidance.
</Note>

## Read definition

The `read` section defines what data to read from the provider. This section is optional - if your integration only writes data or uses proxy, you can omit this section. Learn more in [Read Actions](/read-actions).

```yaml theme={null}
read:
  objects:
    - objectName: contact
      destination: defaultWebhook
      schedule: "*/30 * * * *"
      requiredFields:
        - fieldName: firstname
        - fieldName: lastname
      optionalFields:
        - fieldName: phone
      backfill:
        defaultPeriod:
          fullHistory: true
```

| Field     | Type  | Required | Description                                                                                                                                 |
| --------- | ----- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `objects` | Array | Yes      | An array of [objects to read](#read-object) from the provider. Each element defines a specific object type (e.g., contacts, leads) to read. |

<Note>
  Read considerations

  * Check the specific [provider guide](/provider-guides/overview) to see which objects support reading.
  * For complex integrations, consider combining read actions with [subscribe actions](#subscribe-definition) to get both historical data and real-time updates.
  * See [Read Actions documentation](/read-actions) for detailed implementation guidance.
</Note>

## Write definition

The `write` section defines what data can be written to the provider. This section is optional - if your integration only reads data, subscribes to events, or uses proxy, you can omit this section. Learn more in [Write Actions](/write-actions).

```yaml theme={null}
write:
  objects:
    - objectName: contact
      inheritMapping: true
```

| Field     | Type  | Required | Description                                                                                                                                                |
| --------- | ----- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objects` | Array | Yes      | An array of [objects to write](#write-object) to the provider. Each element defines a specific object type (e.g., contacts, leads) that can be written to. |

<Note>
  Write Considerations

  * Check the specific [provider guide](/provider-guides/overview) to see which objects support writing.
  * When `inheritMapping: true` is set, field mappings defined in the read definition will also be used for writing, which simplifies definition for bidirectional syncs.
  * See [Write Actions documentation](/write-actions) for detailed implementation guidance.
</Note>

## Proxy definition

The `proxy` section configures API call proxying. This allows direct access to the provider's API through Ampersand's proxy. This section is optional - if your integration does not need to make proxy calls, you can omit this section. Learn more in [Proxy Actions](/proxy-actions).

```yaml theme={null}
proxy:
  enabled: true
```

| Field     | Type    | Required | Description                                                      |
| --------- | ------- | -------- | ---------------------------------------------------------------- |
| `enabled` | Boolean | No       | Whether proxy is enabled for this integration. Default: `false`. |

## Object-level definition

### Read object

Each object in the `objects` array defines a specific data type to read from the provider:

| Field                | Type   | Required | Description                                                                                                                                                                                                                     |
| -------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objectName`         | String | Yes      | The [name of the object](#object-name) to read (e.g., `contact`, `lead`, `account`). This must match an object type supported by the provider's API (see note below). Case-sensitive.                                           |
| `destination`        | String | Yes      | The [webhook destination](#destination) for the read data. This determines where the data will be sent after it's read. Must match a webhook configured in your Ampersand account. See [Destinations](/destinations) for setup. |
| `schedule`           | String | Yes      | A [cron schedule](#schedule) for reading the data. Defines how frequently the data should be read. Uses standard cron syntax. Examples: `*/10 * * * *` (every 10 minutes), `0 0 * * *` (daily at midnight).                     |
| `enabled`            | String | No       | If set to `always`, the integration automatically installs upon user connection and skips the user field selection step.                                                                                                        |
| `backfill`           | Object | No       | [Configuration for backfilling](#backfill) historical data. Defines how historical data should be loaded. See [backfill behavior](/read-actions#backfill-behavior) for details.                                                 |
| `requiredFields`     | Array  | No       | Fields that are always read for every customer. These fields will always be included in the data that's read. See [Field Configuration](#field) for more details.                                                               |
| `optionalFields`     | Array  | No       | Optional fields that can be included. Customers can choose which of these fields to include. See [Field Configuration](#field) for more details.                                                                                |
| `optionalFieldsAuto` | String | No       | Set to `all` to automatically include all available fields. This can be used instead of explicitly listing optional fields.                                                                                                     |
| `mapToName`          | String | No       | An optional name mapping for this object. Used to standardize object names across different providers. See [Object and Field Mapping](/object-and-field-mapping) for details.                                                   |
| `mapToDisplayName`   | String | No       | An optional display name mapping for this object. Used for UI display.                                                                                                                                                          |

<Note>
  When configuring fields for a read object, keep these points in mind:

  * You can combine `requiredFields` and `optionalFields` in the same object definition.
  * For detailed options on configuring individual fields, see the [Field Configuration](#field) section.
  * Learn more about [Object and Field Mapping](/object-and-field-mapping).
</Note>

### Write object

| Field            | Type    | Required | Description                                                                                                                                            |
| ---------------- | ------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `objectName`     | String  | Yes      | The [name of the object](#object-name) to write to. Must match an object type supported by the provider's API. Case-sensitive.                         |
| `inheritMapping` | Boolean | No       | Whether to inherit mappings from read definition. If `true`, field mappings defined in the read definition will be used for writing. Default: `false`. |

### Subscribe Object

Each object in the `objects` array defines a specific object type to subscribe to:

| Field                     | Type    | Required    | Description                                                                                                                                                                                                              |
| ------------------------- | ------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `objectName`              | String  | Yes         | The [name of the object](#object-name) to subscribe to. Must match an object type supported by the provider. Case-sensitive.                                                                                             |
| `destination`             | String  | Yes         | The [webhook destination](#destination) for the event data. This determines where the event data will be sent. Must match a webhook configured in your Ampersand account. See [Destinations](/destinations) for setup.   |
| `inheritFieldsAndMapping` | Boolean | Conditional | Whether to inherit field mappings from read configuration. Required and must be set to `true` when the object uses `createEvent`, `updateEvent`, or `deleteEvent`. Not required for objects that only use `otherEvents`. |
| `createEvent`             | Object  | No          | Configuration for create events. See [Event Configuration](#subscribe-action-events) below.                                                                                                                              |
| `updateEvent`             | Object  | No          | Configuration for update events. See [Event Configuration](#subscribe-action-events) below.                                                                                                                              |
| `deleteEvent`             | Object  | No          | Configuration for delete events. See [Event Configuration](#subscribe-action-events) below.                                                                                                                              |
| `associationChangeEvent`  | Object  | No          | Configuration for association change events.                                                                                                                                                                             |
| `otherEvents`             | Array   | No          | Array of non-standard events to subscribe to (e.g., `object.merged`, `object.restored`).                                                                                                                                 |

## Details

### Object Name

The `objectName` must match the API object name in the provider's system. Some common examples:

* Salesforce: `contact`, `lead`, `account`, `opportunity`
* HubSpot: `contacts`, `companies`, `deals`, `tickets`
* GitHub: `repos`, `issues`, `pulls`, `users`
* Intercom: `contacts`, `companies`, `conversations`, `teams`

See the [Provider Guides](/provider-guides/overview) for provider-specific object names.

### Destination

The `destination` field must match a destination configured in your Ampersand dashboard. Common patterns for naming include:

* Provider-specific webhooks: `salesforceWebhook`, `hubspotKinesisStream`, `intercomWebhook`
* Generic webhooks: `defaultWebhook`, `dataStream`, `analyticsWebhook`

> Learn more in [Destinations](/destinations).

### Schedule

The `schedule` field uses standard cron syntax with five fields:

```
┌───────────── minute (0 - 59)
│ ┌─────────── hour (0 - 23)
│ │ ┌───────── day of month (1 - 31)
│ │ │ ┌─────── month (1 - 12)
│ │ │ │ ┌───── day of week (0 - 6) (Sunday to Saturday)
│ │ │ │ │
│ │ │ │ │
* * * * *
```

Common patterns:

* `*/10 * * * *`: Every 10 minutes
* `*/30 * * * *`: Every 30 minutes

<Note>
  Scheduling Considerations

  * Higher frequency (e.g., every 10 minutes) provides more up-to-date data but increases API usage.
  * Lower frequency (e.g., daily) reduces API usage but data may be less current.
  * Consider the provider's API rate limits when setting schedules.
  * For less frequently updated data (e.g., user profiles), a lower frequency may be sufficient.
  * For rapidly changing data (e.g., chat messages), a higher frequency is recommended.
</Note>

### Backfill

The `backfill` section configures how historical data is loaded.

> Learn more about [backfill behavior](/read-actions#backfill-behavior):

```yaml theme={null}
backfill:
  defaultPeriod:
    fullHistory: true
```

| Field                       | Type    | Required | Description                                                                                    |
| --------------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------- |
| `defaultPeriod`             | Object  | No       | The default time period for backfilling.                                                       |
| `defaultPeriod.fullHistory` | Boolean | No       | Whether to backfill the full history (`true`) or just recent data (`false`). Default: `false`. |
| `defaultPeriod.days`        | Number  | No       | The number of days to backfill. Default: `0`.                                                  |

<Note>
  Backfill Considerations

  * Setting `fullHistory: true` may result in longer initial sync times, especially for large datasets.
  * Some providers may have API rate limits that affect backfill performance.
  * See [Read Actions backfill behavior](/read-actions#backfill-behavior) for detailed implementation guidance.
</Note>

### Field

In [Read Actions](#read-actions), fields can be configured in two main ways - either using a simple `fieldName` reference or using a mapped field approach (`mapToName`, `mapToDisplayName`, `prompt`, `default`). This flexibility allows for both direct field references and more sophisticated field mapping options.

> Learn more about [Object and Field Mapping](/object-and-field-mapping) and [Dynamic Field Mappings](/object-and-field-mapping#dynamic-field-mappings).

**Simple Field Reference**

For straightforward field access where you directly reference a provider's field without renaming it:

```yaml theme={null}
- fieldName: firstname
```

<Tip>
  This approach is best when:

  * The field name in the provider's API is already meaningful to your application
  * You don't need to standardize field names across different providers
  * No user configuration is needed for the field
</Tip>

**Field Mapping**

For more complex scenarios, you can use field mapping to standardize field names or prompt users for configuration.

> Learn more about [field mapping strategies](/object-and-field-mapping#field-mapping-strategies).

```yaml theme={null}
# Predefined mapping (no user input required)
- fieldName: mobilephone
  mapToName: phone
  mapToDisplayName: Phone Number

# User-defined mapping (prompts user during setup)
- mapToName: priority
  mapToDisplayName: Priority Score
  prompt: Which field do you use to track the priority of a lead?
  default: priority_level  # Optional default value
```

<Tip>
  Field mapping is useful when:

  * You want to standardize field names across different providers
  * Different customers use different field names for the same concept
  * You need to provide user-friendly display names
  * You want to prompt users to select the appropriate fields during setup

  See [Dynamic Field Mappings](/object-and-field-mapping#dynamic-field-mappings) for implementation details.
</Tip>

| Field              | Type   | Required | Description                                                                                                                                                                                                                                                                                                     |
| ------------------ | ------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `fieldName`        | String | Yes\*    | The name of the field in the provider's API. Must match a field available in the provider's API for the specified object. Case-sensitive. For nested fields, use JSONPath bracket notation (e.g. `$['parentField']['childField']`). See [Nested field mapping](/object-and-field-mapping#nested-field-mapping). |
| `mapToName`        | String | No\*     | An optional name mapping for this field. Used to standardize field names across different providers.                                                                                                                                                                                                            |
| `mapToDisplayName` | String | No\*     | An optional display name mapping for this field. Used for UI display.                                                                                                                                                                                                                                           |
| `prompt`           | String | No\*     | An optional prompt to show when configuring this field. Helps users understand what the field is for.                                                                                                                                                                                                           |
| `default`          | String | No       | An optional default field name to suggest when prompting users. Should only use standard fields as defaults.                                                                                                                                                                                                    |

\*Either `fieldName` or all of `mapToName`, `mapToDisplayName`, and `prompt` are required.

**Common Patterns and Best Practices**

1. **Direct Field Access**: Use simple `fieldName` references for standard, unchanging fields:
   ```yaml theme={null}
   - fieldName: email
   - fieldName: firstname
   - fieldName: lastname
   ```

2. **Standardized Field Names**: Use `fieldName` with `mapToName` to standardize field names:
   ```yaml theme={null}
   - fieldName: FirstName  # Salesforce
     mapToName: first_name
   - fieldName: firstname  # HubSpot
     mapToName: first_name
   ```

3. **User-Defined Mapping**: Use `mapToName` without `fieldName` when users need to select the field:
   ```yaml theme={null}
   - mapToName: notes
     mapToDisplayName: Contact Notes
     prompt: Select the field where you store notes about your contacts
   ```

4. **Combined Approach**: For complex integrations, combine these patterns:
   ```yaml theme={null}
   requiredFields:
     - fieldName: email  # Direct field access
     - fieldName: firstname
       mapToName: first_name  # Standardized name
   optionalFields:
     - mapToName: lead_source  # User-defined mapping
       mapToDisplayName: Lead Source
       prompt: Which field tracks where this lead came from?
   ```

> Learn more about [Object and Field Mapping](/object-and-field-mapping).

### Subscribe action events

In [Subscribe Actions](/subscribe-actions), each event type can be configured with specific options:

**Create event**

The `createEvent` definition specifies how to handle create events:

```yaml theme={null}
createEvent:
  enabled: always
```

| Field     | Type   | Required | Description                                                             |
| --------- | ------ | -------- | ----------------------------------------------------------------------- |
| `enabled` | String | Yes      | Whether to enable create events. Currently, only `always` is supported. |

**Update event**

The `updateEvent` definition specifies how to handle update events:

```yaml theme={null}
updateEvent:
  enabled: always
  watchFieldsAuto: all  # Options: "all" or "selected"
```

Or alternatively:

```yaml theme={null}
updateEvent:
  enabled: always
  requiredWatchFields:  # Watch specific fields
    - name
    - email
    - phone
```

| Field                 | Type   | Required | Description                                                                                                                |
| --------------------- | ------ | -------- | -------------------------------------------------------------------------------------------------------------------------- |
| `enabled`             | String | Yes      | Whether to enable update events. Currently, only `always` is supported.                                                    |
| `watchFieldsAuto`     | String | No\*     | `all` watches all fields for changes. `selected` watches only user-selected fields when `inheritFieldsAndMapping` is true. |
| `requiredWatchFields` | Array  | No\*     | An array of field names to watch for changes. These can include mapped fields.                                             |

<Note>Only one of `watchFieldsAuto` or `requiredWatchFields` should be specified.</Note>

**Delete event**

The `deleteEvent` definition specifies how to handle delete events:

```yaml theme={null}
deleteEvent:
  enabled: always
```

| Field     | Type   | Required | Description                                                             |
| --------- | ------ | -------- | ----------------------------------------------------------------------- |
| `enabled` | String | Yes      | Whether to enable delete events. Currently, only `always` is supported. |

**Association change event**

The `associationChangeEvent` definition specifies how to handle association change events:

```yaml theme={null}
associationChangeEvent:
  enabled: always
  includeFullRecords: true
```

| Field                | Type    | Required | Description                                                                         |
| -------------------- | ------- | -------- | ----------------------------------------------------------------------------------- |
| `enabled`            | String  | Yes      | Whether to enable association change events. Currently, only `always` is supported. |
| `includeFullRecords` | Boolean | No       | Whether to include full records in the event payload. Default: `false`.             |

**Other events**

The `otherEvents` array allows you to subscribe to non-standard events specific to certain providers:

```yaml theme={null}
otherEvents:
  - object.merged
  - object.restored
```

<Tip>
  Combine subscribe actions with read actions to get a complete picture of your customers' data:

  * Use read actions with backfill to get initial historical data
  * Use subscribe actions to get real-time updates going forward
  * Learn more about [combining read and subscribe actions](/subscribe-actions#specify-backfill-behavior)
</Tip>
