From e368b942b4e783b1f80325380c0bb800aca79bb0 Mon Sep 17 00:00:00 2001 From: Anusha Talasila Date: Fri, 11 Sep 2026 10:14:56 -0700 Subject: [PATCH] docs: explain config overrides and add starter project guide --- src/concepts.mdx | 124 +++++++++++++++++++++++++--- src/docs.json | 1 + src/embeddable-ui-components.mdx | 2 +- src/generate-docs.ts | 1 + src/quickstart.mdx | 27 +++--- src/starter-project.mdx | 137 +++++++++++++++++++++++++++++++ 6 files changed, 267 insertions(+), 25 deletions(-) create mode 100644 src/starter-project.mdx diff --git a/src/concepts.mdx b/src/concepts.mdx index 460ca1a5..762ad59c 100644 --- a/src/concepts.mdx +++ b/src/concepts.mdx @@ -1,25 +1,125 @@ --- title: "Concepts" +description: "How integrations, installations, revisions, and configs fit together." --- +Ampersand has one core idea: **you define an integration once, and each of your customers gets their own installation of it.** + +You describe what the integration can do in a manifest file. Each customer then connects their own account and chooses how much of that to enable. Ampersand stores those choices as a config and runs the integration against that customer's SaaS instance on their behalf. + +```mermaid +flowchart TD + A["amp.yaml
what the integration can do"] -->|amp deploy| B["Revision
a versioned snapshot"] + B --> C["Your customer connects
and picks objects and fields"] + C --> D["Installation"] + D --> E["Connection
their credentials"] + D --> F["Config
what they chose"] + B --> G["What actually runs
= revision, with config overrides applied"] + F --> G +``` + ## Integration -An **integration** defines how your application will interact with a third party SaaS tool. You will have a single integration for all of your customers that are connecting your application with a particular SaaS product. For example, you might have an integration called `mySalesforceIntegration`. Salesforce is the **provider** that we are integrating with. +An **integration** defines how your application interacts with a third-party SaaS tool. You have a single integration for every customer connecting to that provider. For example, one integration called `mySalesforceIntegration`, where Salesforce is the **provider**. + +You create an integration by defining it in a [manifest file](/manifest-reference) and deploying it with the [`amp` CLI](/cli/overview). -You create an integration by defining it in a [manifest file](/manifest-reference) and then deploying it using the `amp` CLI. (See [CLI Overview](/cli/overview)). +The manifest describes what is *possible*, not what any particular customer has turned on. It can say: -An **installation** is specific to a single customer that sets up one of your integrations to connect with their SaaS instance. For example, `mySalesforceIntegration` might have 30 installations - one for each of your customers that have connected their Salesforce instance with your application. +- objects and fields that are always read (`requiredFields`) +- fields the customer may choose from (`optionalFields`, or `optionalFieldsAuto: all`) +- fields the customer must map to their own schema (`mapToName`) +- a schedule, a destination, and backfill behavior ## Installation -An installation is an instance of an integration, for a particular customer. It is created: -- when a customer connects their SaaS instance in an [embeddable UI component](/embeddable-ui-components) -- or when you make an API call to the [CreateInstallation](/reference/installation/create-a-new-installation) endpoint. - -An installation captures the following information: -- the credentials for connecting to the customer's SaaS instance. (Ampersand supports OAuth, Basic Auth, and API Key based authentication.) We call this the **connection**. -- a customer's preference for which objects and fields they want your application to read or write, and fields they've mapped. We call this the **config**. +An **installation** is one customer's instance of an integration. `mySalesforceIntegration` might have 30 installations, one per customer who has connected their Salesforce. ---- +An installation is created when a customer connects through an [embeddable UI component](/embeddable-ui-components), or when you call the [Create installation](/reference/installation/create-a-new-installation) endpoint. + +Each installation holds two things: + + + + The credentials for that customer's SaaS instance. Ampersand supports OAuth, API keys, and basic auth, and handles token refresh for you. + + + That customer's choices, stored as overrides on the integration's definition: fields, mappings, schedule, and destination. + + + +## Revision + +Every time you change `amp.yaml` and run `amp deploy`, Ampersand stores a new **revision**, a versioned snapshot of the integration's definition. + +Revisions matter because your customers are not all on the same version at the same moment. A config records the revision it was created or last updated against, so you can tell which definition a given customer is running. + + +When Ampersand renders the field-mapping UI, it requests a **hydrated revision**: the revision enriched with live field metadata from that customer's connected instance. It carries the fields that actually exist in their account, with display names and types. That is how the UI can offer a customer *their* custom fields, not a generic list. + + +## Config + +The **config** records one customer's choices for an installation. It is not a complete description of what runs. It is a set of **overrides on top of the revision**. + + +Anything the config specifies wins for that installation. Anything it leaves unset falls back to what the integration's revision defines. A config is a diff, not a replacement. + + +This is why two customers on the same integration can behave differently without you maintaining two manifests, and why a customer who has changed nothing simply follows what you declared. + +### What a config can override + +For a read object, a config can set the fields the customer selected (`selectedFields`, or `selectedFieldsAuto: all`), the mappings they chose (`selectedFieldMappings`, `selectedValueMappings`), and operational settings: `schedule`, `destination`, `backfill`, `fieldFilters`, and `disabled` to pause an object entirely. For a write object it can set `deletionSettings`, `selectedFieldSettings`, and `selectedValueDefaults`. + +### A worked example + +Suppose your manifest declares: + +```yaml +- objectName: contact + destination: contactsWebhook + schedule: "*/15 * * * *" + requiredFields: + - fieldName: email + - mapToName: lifecycle_stage + optionalFieldsAuto: all +``` + +A customer installs it and maps `lifecycle_stage` to their `hs_lead_status` field, adds two optional fields, and leaves everything else alone. Their config carries only those choices. + +What actually runs for them is the merge: `email` and their two optional fields are read, `hs_lead_status` is mapped to `lifecycle_stage`, and the schedule and destination come from your revision, because the config never mentioned them. + +If that customer later asks for hourly syncs, you set `schedule` on their config. It now overrides yours, for them alone. Every other installation still follows the manifest. + +You can read a config with [Get an installation](/reference/installation/get-an-installation), or from the SDK via `installation.config`, and change one with [Update an installation](/reference/installation/update-an-installation). + +## How they work together + + + + `amp deploy` creates a revision from your `amp.yaml`. Nothing runs yet. You have only described what is possible. + + + They authenticate against their own SaaS instance through your embedded UI. Ampersand stores those credentials as a connection. + + + Ampersand hydrates the revision with the live schema from their instance, and the UI offers the fields your manifest allows. Their selections become the config. + + + Scheduled reads, writes, and subscriptions execute against that customer's instance, using your revision with their config's overrides applied, and deliver results to your destination. + + + +### What this means in practice + +- **One integration, many configs.** Two customers on the same integration can legitimately read different field sets. That is the design, not drift. +- **A config only carries what the customer changed.** Everything else follows your manifest, so defaults stay in one place. +- **To change one customer, update their config.** To change the default for everyone, change the manifest and deploy. +- **Mapped fields need a customer decision.** A `mapToName` entry cannot resolve until someone tells Ampersand which of their fields it corresponds to. + +## Related terms + +A **provider** is the third-party API you integrate with. A **provider app** is the OAuth app you register with that provider, stored in Ampersand so customers can authenticate against it. A **destination** is where read results are delivered: a webhook, warehouse, or queue. -For other terminology, refer to [Terminology](/terminology). +For the full glossary, see [Terminology](/terminology). diff --git a/src/docs.json b/src/docs.json index 015cf840..a6550663 100644 --- a/src/docs.json +++ b/src/docs.json @@ -25,6 +25,7 @@ "overview", "concepts", "quickstart", + "starter-project", "use-with-ai-ide" ] }, diff --git a/src/embeddable-ui-components.mdx b/src/embeddable-ui-components.mdx index 2f55463e..5e2bbe8c 100644 --- a/src/embeddable-ui-components.mdx +++ b/src/embeddable-ui-components.mdx @@ -6,7 +6,7 @@ title: "Prebuilt UI components" ### Prerequisites -- You need a React app to embed the components into. If you don't already have one, you can use the [Ampersand starter project](https://github.com/amp-labs/starter-project). +- You need a React app to embed the components into. If you don't already have one, you can use the [Ampersand starter project](/starter-project). - The Ampersand UI library requires **React v18+**. ### Install the Ampersand React library diff --git a/src/generate-docs.ts b/src/generate-docs.ts index b24e286d..ab191bc4 100644 --- a/src/generate-docs.ts +++ b/src/generate-docs.ts @@ -264,6 +264,7 @@ const baseConfig = { "overview", "concepts", "quickstart", + "starter-project", "use-with-ai-ide", ], }, diff --git a/src/quickstart.mdx b/src/quickstart.mdx index 489432da..9f2e8f0b 100644 --- a/src/quickstart.mdx +++ b/src/quickstart.mdx @@ -1,17 +1,21 @@ --- title: "Quickstart" +description: "Build your first integration end to end: define a manifest, deploy it, and embed the install UI." --- -For this Quickstart, we are going to build integrations for a cool new app called MailMonkey - an AI-powered email campaign manager that integrates with Salesforce. You can see the final `amp.yaml` file on [Github](https://github.com/amp-labs/samples/blob/main/quickstart/amp.yaml). +For this Quickstart, we are going to build integrations for a cool new app called MailMonkey, an AI-powered email campaign manager that integrates with Salesforce. You can see the final `amp.yaml` file on [Github](https://github.com/amp-labs/samples/blob/main/quickstart/amp.yaml). - + + MailMonkey logo + ## Create an Ampersand org and project Sign up for an [Ampersand account](https://dashboard.withampersand.com/sign-up), and then follow the steps on the screen to create an org and then a project. Each org can have multiple projects, this is helpful for separating development and production environments. -### Claim your domain -Claim your domain to let teammates auto-join your organization when they sign up. You can do this as an org owner in the dashboard under org settings. Once enabled, anyone with a `@yourcompany.com` email will automatically be added to your org. +## Claim your domain + +Claim your domain to let teammates auto-join your organization when they sign up. As an org owner, you can do this in the dashboard under org settings. Once enabled, anyone signing up with a `@yourcompany.com` email joins your org automatically, so teammates do not need an invite. ## Create a provider app @@ -19,7 +23,7 @@ We'll first set up a Salesforce Connected App and put the Client ID and Client S ## Create a destination -Next, we create a webhook destination for Ampersand to send data that it reads from Salesforce. See [Destinations](destinations) for more details. +Next, we create a webhook destination for Ampersand to send data that it reads from Salesforce. See [Destinations](/destinations/overview) for more details. ## Define the integrations @@ -34,7 +38,7 @@ Let's create a folder called `source`, with a file inside called `amp.yaml`, thi Our integration will have a [Read Actions](/read-actions). We'll read 2 objects from Salesforce: contacts and leads. -```YAML YAML +```yaml amp.yaml specVersion: 1.0.0 integrations: - name: mailmonkey-salesforce @@ -80,8 +84,7 @@ integrations: Next we will add a [Write Action](/write-actions). We want to insert new leads into our customer's Salesforce. - -```YAML YAML +```yaml amp.yaml ... # Append to the integration definition from above. write: @@ -98,7 +101,7 @@ You can see the final `amp.yaml` file on [Github](https://github.com/amp-labs/sa Once we are happy with the definition of our integrations, we can deploy them with the [amp CLI](/cli/overview): -``` +```bash Deploy amp login # Our amp.yaml file is located in a folder called source. amp deploy source --project=my-project-id-or-name @@ -106,11 +109,11 @@ amp deploy source --project=my-project-id-or-name ## Embed UI components -Next, we will use Ampersand's react library to embed ready-made UI components into our app, so that our customers can start using our shiny new integrations! We'll use the `InstallIntegration` component for the auth flow and configuration steps. Check out [Embed UI components](/embeddable-ui-components) for more details on this component and other components to help your users set up and manage their integrations. If you don't already have a frontend codebase, you can use our [Starter Project](https://github.com/amp-labs/starter-project/tree/main). +Next, we will use Ampersand's react library to embed ready-made UI components into our app, so that our customers can start using our shiny new integrations! We'll use the `InstallIntegration` component for the auth flow and configuration steps. Check out [Embed UI components](/embeddable-ui-components) for more details on this component and other components to help your users set up and manage their integrations. If you don't already have a frontend codebase, you can use our [starter project](/starter-project). Here's a simplified version of what our frontend code would look like: -```TypeScript TypeScript +```tsx App.tsx import { AmpersandProvider, InstallIntegration } from '@amp-labs/react'; const options = { @@ -123,7 +126,7 @@ function App() { + + A minimal React and Vite app that embeds the `InstallIntegration` component, so you can watch a customer connect their account. + + + A HubSpot integration defined in `integrations/amp.yaml`, reading contacts and companies and writing back to both. + + + + +Prefer to build it yourself? The [Quickstart](/quickstart) walks through the same ground from an empty directory, explaining each piece as you add it. The starter project gets you to a running app faster; the Quickstart teaches you more along the way. + + +## Before you start + +Setting up the accounts and credentials takes longer than running the app itself. Budget around twenty minutes for these steps the first time. + + + + Sign up for a [free Ampersand account](https://dashboard.withampersand.com/sign-up) and follow the prompts to create a project. + + + In the dashboard, open [API keys](https://dashboard.withampersand.com/projects/_/api-keys) and create one. You will paste it into the app later. + + + In [Destinations](https://dashboard.withampersand.com/projects/_/destinations), create a webhook destination called `defaultWebhook`. If you do not have an endpoint to point it at, [play.svix.com](https://play.svix.com) gives you a disposable one that shows incoming payloads in the browser, which is ideal for a first run. + + + The included integration uses HubSpot, so you need a HubSpot account and a HubSpot app. Follow the [HubSpot provider guide](/provider-guides/hubspot). To use a different provider instead, pick its [provider guide](/provider-guides/overview) and swap the manifest in the next section. + + + Install the [Ampersand CLI](/cli/overview) and run `amp login` to authenticate. + + + +## Run it + + + + ```bash + git clone https://github.com/amp-labs/starter-project.git + cd starter-project + npm install + ``` + + + ```bash + amp deploy integrations -p + ``` + This creates a [revision](/concepts#revision) of the integration from `integrations/amp.yaml`. Nothing syncs yet, because no customer has installed it. + + + In `src/App.tsx`, replace the placeholders with your project name and API key: + + ```tsx + const options = { + project: 'MY-PROJECT-NAME', + apiKey: 'MY-API-KEY', + }; + ``` + + + ```bash + npm run dev + ``` + Open the app and use the embedded component to connect a HubSpot account. Once installed, reads run on the schedule in the manifest and results arrive at your `defaultWebhook` destination. + + + +## What the code does + +The whole integration surface is one component. `AmpersandProvider` holds your project credentials, and `InstallIntegration` renders the connect and configure flow your customers see: + +```tsx src/App.tsx +import { AmpersandProvider, InstallIntegration } from '@amp-labs/react' +import '@amp-labs/react/styles'; + +const options = { + project: 'MY-PROJECT-NAME', + apiKey: 'MY-API-KEY', +}; + +function App() { + const integration = "hubspotCRM"; // must match the name in integrations/amp.yaml + + return ( + + + + ) +} +``` + +The `consumerRef` and `groupRef` values identify which of your customers is installing. In your own application these come from your user and account records, not hardcoded strings. See [Prebuilt UI components](/embeddable-ui-components) for the full set of props. + +## Make it yours + + + + Replace `integrations/amp.yaml` with your own manifest, or with one from the [samples repository](https://github.com/amp-labs/samples). See the [manifest schema](/manifest-reference) for every available field. + + + Three names have to match up: the integration name in `amp.yaml` and the `integration` variable in `App.tsx`, and the destination name in `amp.yaml` and the destination you created in the dashboard. + + + Run `amp deploy` again whenever you edit the manifest. Each deploy creates a new revision. Settings a customer has already overridden in their [config](/concepts#config) stay as they set them. + + + +## Where to go next + + + + Integrations, installations, revisions, and configs. + + + Schedules, backfills, field filters, and delivery. + + + Props, theming, and the other components in the library. + +