Define reads
To read an object, you need to specify:- objectName: to indicate which object you’d like to read. This should match the name of the object in the official documentation for the SaaS API.
- destination: the name of the destination that you’ve defined
- schedule (optional): how frequently the read should happen. This value must be a schedule in cron syntax, and can be as frequent as every 10 minutes. If you do not define a schedule, you can explicitly trigger reads via API.
- backfill (optional): whether Ampersand should read historical data when a customer installs an integration. See Backfill behavior for details. If you omit this, it means that a backfill won’t happen at the time of installation, but you can still trigger a backfill later via API.
YAML
Required fields and optional fields
Fields can either be required or optional. If a field is required, then all users who install this integration will need to give your app read access to that field. If a field is optional, then users can choose whether they’d like your app to read that field. For these fields, you will specify:- fieldName: the name of the field from the official SaaS API documentation.
YAML
Nested fields
Some providers return data with nested structures. You can reference nested fields using JSONPath bracket notation:$['parentField']['childField'].
This works in both requiredFields and optionalFields, with or without field mapping:
YAML
Allow users to pick from all fields
If you want to give your user the option to pick from any of the fields in their object, useoptionalFieldsAuto: all. The UI component will populate a list of all the fields pulled from that object (including custom fields) and allow them to pick which ones your app will be able to read.
YAML
Object and field mappings
You might want to ask your users during the set up of the integration to map a field (standard or custom) to a concept in your product, because your various customers might be using different fields for the same purpose. You can also predefine object and field mappings that do not involve user interaction. Learn more in Object and Field Mapping.Always-enabled objects
By default, each customer chooses which objects to read when they install your integration. Setenabled: always on an object to read it for every installation instead. Customers can’t turn it off, but they can still pick its optional fields and mappings.
Because the object is read without asking the customer, it can’t have required field mappings: every required field needs a fieldName, so there’s nothing the customer must choose. Optional field mappings are fine.
YAML
- New installations: Ampersand adds the object to the installation’s config when the installation is created or imported, even if the config doesn’t include it. It’s then validated, scheduled and backfilled like any other object.
- Existing installations: when you deploy an
amp.yamlthat adds a new object withenabled: always, or adds the flag to an existing object, Ampersand updates the config of every existing installation that doesn’t have the object, as part of the deploy. An installation’s own entry for the object, with its selected fields and mappings, is never overwritten. If the sample read fails for an installation, that installation isn’t updated. Updating an installation through the API doesn’t add missing always-enabled objects; only creating one does. - Prebuilt UI: the
InstallIntegrationcomponent installs these objects as soon as the customer connects, and adds a missing one when the customer opens an existing installation.
- A config that sets
disabled: trueon an always-enabled object is rejected with an HTTP400response. - The object needs at least one entry in
requiredFields, and none of them can be a mapping the customer fills in (amapToNamewithout afieldName). A deploy that breaks either rule is rejected.
enabled: always, installations that already have the object keep reading it. New installations stop getting it automatically.
Backfill behavior
Backfill behavior describes whether Ampersand will do an initial read of your customer’s historic data when they connect their SaaS instance, and how far back data will be read. For example, if your integration reads a customer’s contacts stored in their CRM, you can configure whether you want to only read new and updated contacts going forward, or if you also want to do an initial backfill of the pre-existing contacts in their CRM.No backfill
If you only want to read new and updated records moving forward and do not wish to read any pre-existing records, then you can simply omit thebackfill key in the integration definition, or you can write 0 days as the default period.
YAML
Full historical backfill
If you want to do a full backfill of all the existing records when a customer connects their SaaS instance, setfullHistory to true. If you have customers that have large SaaS instances, please ensure that your webhook endpoint can handle a high number of messages in quick succession. You may find it helpful to use a webhook gateway solution like Hookdeck.
yaml
Limited time backfill
You can select a specific time frame for backfill, such as “the last 30 days” or “the last 90 days”. Here’s an example of how to do so:yaml
Monitor backfill progress
To monitor the progress of your backfill, poll the backfill progress API for an installation and object. Call it while the backfill runs to track sync status. The API returns:- recordsProcessed — How many records have been synced so far; updates as the backfill runs
- recordsEstimatedTotal — The estimated total at the start of the backfill, if it is available.
- operationId — The ID of the backfill operation
- createTime — When the backfill started
- updateTime — When progress was last updated
Filter by field values
You can filter which records are returned by a read action by settingfieldFilters in the installation config when you are creating the installation using the REST API or Headless UI’s createInstallation method. Then only matching records are read and delivered to your destination.
Each filter specifies a field name, an operator, and a value. Currently, only the eq (equals) operator is supported. Multiple filters are joined with AND logic, and each field can only have one condition.
Filtered reads are currently only supported for Salesforce (CRM Module) and HubSpot.
Filter all records
To filter both incremental reads and backfill, setfieldFilters on the object in the installation config when you are creating the installation using the REST API or Headless UI’s createInstallation method:
firstname equals “Brian” will be returned during both scheduled reads and backfill.
Backfill-specific filters
If you want different filter behavior for backfill vs. incremental reads, you can setfieldFilters inside the backfill object. When set, this overrides the object-level fieldFilters during backfill. Please note that triggered reads will still use the object-level fieldFilters, if it is defined.
firstname equals “Brian”, while subsequent incremental reads will only return contacts whose status equals “active”.
Filter field names
ThefieldName of a filter must be the field’s name in the provider’s API, and it is case-sensitive.
For example, if your manifest maps the provider field mobilephone to phone:
mobilephone:
selectedFields. You can filter on a field that you don’t read.
Valid filter values
Thevalue field of the filter accepts strings, booleans, and numbers:
Filter with a raw filter
UserawFilter when you need filtering that fieldFilters can’t express, such as very specific conditions, comparisons, or reading deleted records. A raw filter is written in the provider’s own query syntax and passed to the provider as written.
A raw filter has two parts:
type: the filter syntax. Each provider guide lists the types it supports, for examplesoqlfor Salesforce.filter: the filter expression, in that syntax.
Raw filters are currently only supported for Salesforce using the
soql type. You can learn more about each provider’s raw filter support in its provider guide.fieldFilters:
- Set
rawFilteron the object to filter incremental reads, or insidebackfillto filter only the backfill. A backfill with no filter of its own uses the object’s filter. Triggered reads use the object’s filter. - Only one of
rawFilterorfieldFiltersis supported, on the object and insidebackfill. - A
backfillblock in the installation replaces the backfill settings fromamp.yamlentirely, so abackfillblock that sets a filter must also setdefaultPeriod(daysorfullHistory). - Field names are the provider’s own. Object and field mappings are not resolved.
type, or if the filter isn’t the kind of value that type expects (for soql, a non-empty string). The provider checks the filter’s syntax when a read runs, so try a raw filter with a search before adding it to an installation; searches apply raw filters the same way.
Trigger a read
You can call the trigger read API when you want Ampersand to read data for a particular customer. The data will be sent asynchronously to your destination. You can either use this API alongside a scheduled read (defined by theschedule field in the amp.yaml), or you can exclusively use the trigger read API without defining a schedule.
There are 2 types of reads that can be triggered:
- Full historic read
- Read all records from a specific timestamp to now
Install-time validation
When a customer creates or updates an installation, Ampersand runs a sample read before saving the configuration: a one-record read against the provider for each scheduled read object. This surfaces configuration errors — such as field-level visibility restrictions or misconfigured field names — up front, so your customer sees the problem while they’re still in the install flow instead of discovering it later through a broken sync. Sampling is on by default. No configuration is required. What gets sampled- Only read objects that will run on a schedule (enabled, with a
scheduledefined). Write and subscribe objects are not sampled. - The sample reads the object’s selected fields plus the source fields of any field mappings.
- On create, every scheduled read object is sampled. On update, Ampersand re-samples only what could have changed: newly added objects, objects newly put on a schedule, objects whose field selection changed, or — when the connection is swapped — every scheduled read object.
422 response containing the provider’s error message, and the installation is not saved.
Only bad-request errors block the save. Transient problems — authentication, rate limiting, or provider 5xx errors — are ignored so they don’t stop a legitimate installation on a best-effort probe.
When using the
InstallIntegration component, sampling runs automatically on @amp-labs/react 2.13.5 and later.?skipSampling=true to the create or update installation endpoints. This is useful if you intentionally save configurations before the connected user has been granted the necessary field access. Note that skipping validation means misconfigurations won’t surface until reads actually run.
Full example
yaml
Delivery modes (deprecated)
Ampersand sends data to destinations that you specify in your manifest file. Please refer to webhook destinations for more information on the data schema of the webhooks. You can define the delivery mode within the manifest file.Auto
This is the default delivery mode if you do not specify one. When you set the delivery mode toauto, Ampersand will automatically send results to your destination as it reads new data from the SaaS instance.
yaml
On request (deprecated)
When you set the delivery mode toonRequest, Ampersand will not send webhooks as it reads new data, but only when you request for more results. This is useful when you want to control the rate at which you receive data. For precise control over how much data you receive each time, you can configure the page size, which specifies the number of records to send in each webhook payload.
Please note that the page size is a maximum, and the actual number of records in each payload may be less if there are fewer records available in the SaaS instance. Currently, you may configure a page size between 50 and 500. Please reach out to us if you need this to be lower or higher.
Here’s an example of how to configure the delivery mode to onRequest for a Salesforce Contact object, with a max page size of 50 records per webhook message:
yaml
Requesting results
When you are ready to receive & process webhook messages, you can call the deliver results endpoint, which will asynchronously send the stored results to the configured destination. For example, if you are ready to receive and process a maximum of 300 records, and you have apageSize of 50 in your amp.yaml, you should request 6 pages (300 divided by 50).

