---
name: unified-integration-planner
description: >-
  Plan a Unified.to integration before writing code: turn a use case and a list
  of target vendors (HubSpot, Salesforce, Greenhouse, BambooHR, QuickBooks, …)
  into a per-vendor support table from live data, the minimum scopes to request,
  how each vendor's end users connect, and a sync plan (native webhooks, virtual
  webhooks or polling). Use when a developer asks "which integrations can
  support this feature", "can we offer X, Y and Z for this", "what scopes do we
  need", or before building a feature across several integrations.
license: MIT
metadata:
  category: planning
  api_base: https://api.unified.to
  docs: https://docs.unified.to/integrations
  docs_index: https://docs.unified.to/llms.txt
---

# Plan a Unified.to integration from live support data

Support differs per integration and changes as integrations are updated. A
feature that works for HubSpot may need different fields for Salesforce, and a
vendor may only have polled (virtual) webhooks. This skill finds that out
**before** any code is written, from live data, and turns it into a plan the
developer approves.

The output is a short plan: a support table per vendor, the gaps, the scopes to
request, how end users connect, and how to keep data in sync. Building it is
then the job of `unified-quickstart` and the category skill.

## When to use this skill

- The developer names a feature and several vendors to offer it for.
- The developer asks which integrations can support a feature, or what is
  missing for one vendor.
- Before writing a create/update call, a webhook, or a sync job for an
  integration you have not checked.

Do not use it to build the integration; hand off to the skills listed at the
end.

## Step 1: Pin down the use case

Ask in one batch, and do not guess:

1. **Objects:** which Unified objects, as `<category>_<object>`
   (`crm_contact`, `crm_deal`, `ats_candidate`, `hris_employee`,
   `accounting_invoice`, …). The category skills list them.
2. **Operations per object:** read only (`list`, `get`), or also write
   (`create`, `update`, `remove`).
3. **Fields:** the fields the feature must read and the ones it must write.
4. **Freshness:** real-time (seconds), near-real-time (minutes), or periodic
   (hourly or daily).
5. **Vendors:** which integrations to offer first, by integration type
   (`hubspot`, `salesforce`, `pipedrive`, …). `https://docs.unified.to/integrations.md`
   lists every type.

## Step 2: Look up support for each vendor

Use live data, never memory. In order of preference:

- **Core MCP:** `list_unified_integrations` with `type: "<integration_type>"`.
  If the tool accepts `types` and `object_types`, pass all the vendors and only
  the objects you need in one call; otherwise call it once per vendor.
- **REST:** `GET https://api.unified.to/unified/integration?type=<integration_type>`
  with the workspace API key (EU: `api-eu.unified.to`, AU: `api-au.unified.to`).
  Don't pass `summary=true`; that drops the support data.
- **No API key yet:** read `https://docs.unified.to/integrations/<integration_type>.md`,
  which lists the same data per object. It is updated when the docs are built,
  so prefer the API when you have a key.

From each integration's response, read:

| Field | Tells you |
| --- | --- |
| `support.<object>.methods` | Which of `list`, `get`, `create`, `update`, `remove` work |
| `support.<object>.outbound_fields` | Fields you can read (`supported`) |
| `support.<object>.inbound_fields` | Fields you can write; `supported-required` must be sent on create |
| `support.<object>.list_*` | List filters; `supported-required` must be sent on every list call |
| `support.<object>.webhook_events` | For `created` / `updated` / `deleted`: `native` and/or `virtual` |
| `support.<object>.virtual_webhook_*` | Filters a virtual webhook accepts |
| `api.auth.oauth2` | Present when end users connect with OAuth2 |
| `api.auth.oauth2.scopes` | Each Unified scope (`<object>_read` / `<object>_write`) → vendor scopes |
| `api.auth.oauth2.has_unified_oauth2_credentials` | Whether Unified.to has its own OAuth2 app for this vendor |
| `api.auth.token`, `token_names`, `token_instructions` | End users enter credentials (API key, client ID/secret) instead |

A missing `support.<object>` means the object is not supported. A missing or
`not-supported` method, field or filter means it is not supported; calling an
unsupported method returns `501`.

## Step 3: Build the support table

One row per vendor, one column per requirement from Step 1. Mark each cell
supported, not supported, or supported with a condition, and say what the
condition is. Example for "create deals and get notified when they change":

| Vendor | `crm_deal` create | Required on create | `updated` webhook | Incremental list (`list_updated_gte`) |
| --- | --- | --- | --- | --- |
| hubspot | yes | none | native, virtual | yes |
| salesforce | yes | `name`, `closed_at` | virtual only | yes |
| pipedrive | yes | none | native, virtual | yes |

Then list the **gaps** in plain words: what will not work for which vendor,
and what the app must do differently (send extra required fields, accept a
polling delay, hide a feature for that vendor). Do not code around a gap
silently; the developer decides.

## Step 4: Scopes

- **Unified scopes to request:** for each object, `<object>_read` if the
  feature reads it and `<object>_write` if it writes it. Pass only these in
  `scopes=` on the authorization URL; leaving `scopes` out requests every
  scope.
- **Vendor scopes:** `api.auth.oauth2.scopes` maps each Unified scope to the
  vendor scopes it requests. If the developer registers their own OAuth2 app
  with the vendor, the app must declare those vendor scopes. The vendor's
  `<vendor>-oauth-app` skill covers registration, e.g.
  `https://docs.unified.to/skills/hubspot-oauth-app/SKILL.md`.

## Step 5: How end users connect

Per vendor:

- **OAuth2** (`api.auth.oauth2`): the end user signs in to the vendor. If
  `has_unified_oauth2_credentials` is false, the developer must register an
  OAuth2 app with the vendor and add its credentials to the integration in
  app.unified.to before end users can connect.
- **Credentials** (`api.auth.token`): the end user enters the values named in
  `token_names` (an API key, or a client ID and secret). Show
  `token_instructions` to the end user so they know where to find them.
- Some vendors offer both; say which the app will present.

## Step 6: Sync plan

For each vendor and object, pick the first that is supported:

1. **Native webhook** (`webhook_events.<event>` includes `native`): pushed by
   the vendor, near real time.
2. **Virtual webhook** (`virtual`): Unified.to polls the vendor on an interval
   and delivers changes as webhooks. Expect a delay of about the interval.
3. **Polling** with `updated_gte`, only where `list_updated_gte` is supported:
   list changed records on a schedule.
4. **Full re-list** on a schedule, when none of the above is supported.

If `deleted` is not supported as an event, say how deletions will be noticed
(for example a periodic full list), or that they won't be. Webhook setup,
`include_all` backfill and signature checks are in the `unified-quickstart`
skill (Step 7) and `unified-debug-webhooks-connections`.

## Step 7: Present the plan and wait

Show the developer, in this order:

1. The support table and the gaps (Step 3).
2. The Unified scopes to request and, per vendor, the vendor scopes to declare
   (Step 4).
3. How end users connect, per vendor (Step 5).
4. The sync plan, per vendor and object (Step 6).
5. Where each fact came from (API response or docs page) and when you looked.

Wait for approval before writing code. Once approved, build with:

- `https://docs.unified.to/skills/unified-quickstart/SKILL.md` for workspace
  setup, the authorization flow, the first call and webhooks.
- The category skill for object shapes, e.g.
  `https://docs.unified.to/skills/unified-crm/SKILL.md`.

## Rules

- Never assume support from a vendor's own API or from another integration.
  Unified.to's support data is the contract.
- Re-check support when the plan is old or a call returns `501`; it changes as
  integrations are updated.
- Keep the API key server-side. Don't print it or write it to files.
- When something is unclear, search the docs (`search_docs` on Core MCP, or
  `https://docs.unified.to/llms.txt`) or ask Unified.to support
  (hello@unified.to). Don't invent fields or parameters.
