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

# Map an integration's fields

> Connect any REST or GraphQL system, discover its schema, and map its fields onto your agent — no per-provider code.

When a provider's schema can be introspected, you don't need pre-built actions. You **discover**
its entire data model, then **map** the fields you want onto your agent's parameters. The mapping
*is* the integration. This guide builds a "look up the caller" skill against a connected CRM.

<Note>
  Authenticate every request with a secret API key: `Authorization: Bearer flowyte_sk_…`. Base URL
  `https://builder.flowyte.com/api/v1`.
</Note>

<Steps>
  <Step title="Connect the provider">
    Connect it once for your organization (OAuth approval, or API-key credentials).

    ```bash theme={null}
    curl -X POST https://builder.flowyte.com/api/v1/integrations/acme_crm/connect \
      -H "Authorization: Bearer $FLOWYTE_API_KEY"
    ```
  </Step>

  <Step title="Discover the schema">
    Introspect the provider into a normalized schema. The response summarizes what was found.

    ```bash theme={null}
    curl -X POST https://builder.flowyte.com/api/v1/integrations/acme_crm/discover \
      -H "Authorization: Bearer $FLOWYTE_API_KEY"
    # → { "data": { "objectCount": 38, "fieldCount": 612, "edgeCount": 74, ... } }
    ```
  </Step>

  <Step title="Browse the catalog">
    Read the discovered schema to see the objects, their fields, the relationships between them, and
    the operations you can run. This is the catalog you map from.

    ```bash theme={null}
    curl https://builder.flowyte.com/api/v1/integrations/acme_crm/schema \
      -H "Authorization: Bearer $FLOWYTE_API_KEY"
    ```

    Find the operation you want (here, a `findContact` query) and the fields you want back
    (`contact.name`, `contact.email`).
  </Step>

  <Step title="Author the binding">
    Map the operation onto a skill. **`inputs`** map your agent's parameters to the operation's
    arguments; **`projection`** picks which provider fields come back, each renamed to one of your
    own output names (`leaf`). The mapping is validated against the schema before it's created.

    ```bash theme={null}
    curl -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/integrations/acme_crm/bindings \
      -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
      -d '{
            "toolName": "Look up the caller",
            "description": "Find the calling customer in the CRM by phone and return their name and email.",
            "operation": "findContact",
            "inputs": [
              { "param": "caller_phone", "arg": "phone", "required": true, "description": "The caller'\''s phone number" }
            ],
            "projection": [
              { "path": ["contact", "name"],  "leaf": "customer_name" },
              { "path": ["contact", "email"], "leaf": "customer_email" }
            ],
            "enabled": true
          }'
    ```

    This compiles to a skill on the agent. The agent now calls `Look up the caller` with the caller's
    phone and gets back `customer_name` and `customer_email` — without ever seeing the provider's raw
    field tree.
  </Step>

  <Step title="Publish and test">
    The new skill takes effect on the **published** agent.

    ```bash theme={null}
    curl -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/publish \
      -H "Authorization: Bearer $FLOWYTE_API_KEY"

    curl -N -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/simulate \
      -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
      -d '{ "message": "Hi, it'\''s me calling about my account.", "draftMode": false }'
    ```
  </Step>
</Steps>

## How it fits together

* You map onto **canonical parameters** (`caller_phone`, `caller_name`, `service_address`, …), so
  one mapping concept is reusable across any provider and your agent's prompt never changes.
* The mapping is **validated against the discovered schema** when you save it — a field that
  doesn't exist, or one the operation can't return, is caught up front, not on a live call.
* Set `enabled: false` to save a binding as a **draft** to review before it ships.

<Tip>
  **Don't want to map by hand?** `POST /agents/{agentId}/integrations/{kind}/bindings/auto` takes a
  plain-language goal — "look up a caller by phone and tell me their open tickets" — and the AI
  assistant proposes the whole binding (operation, input mapping, and projection) over the discovered
  schema. It's validated and saved as a **disabled draft** for you to review, then enable.

  ```bash theme={null}
  curl -X POST https://builder.flowyte.com/api/v1/agents/$AGENT_ID/integrations/acme_crm/bindings/auto \
    -H "Authorization: Bearer $FLOWYTE_API_KEY" -H "Content-Type: application/json" \
    -d '{ "goal": "Look up the caller by phone and return their name and open tickets" }'
  ```

  Some providers also ship a **Connector Pack** of ready-made preset skills — install them in one call
  with `POST /agents/{agentId}/integrations/{kind}/pack/install` (read it first with
  `GET /integrations/{kind}/pack`).
</Tip>
