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

# Fitment

> Associate products with vehicle or equipment compatibility targets

Fitment lets you define compatibility targets (e.g., vehicles) and associate them with products. When configured, Remark's AI assistant can help customers narrow down to their specific vehicle and automatically filter search results to compatible parts.

<CardGroup cols={2}>
  <Card title="Facets" icon="layers" href="#facets">
    Define the dimensions of fitment for your catalog (e.g., Year, Make, Model).
  </Card>

  <Card title="Targets" icon="target" href="#targets">
    Create specific fitment targets representing individual configurations.
  </Card>

  <Card title="Product Linking" icon="link" href="#linking-products">
    Associate fitment targets with products during import.
  </Card>

  <Card title="AI Assistant" icon="bot" href="#ai-assistant-behavior">
    How Remark's assistant uses fitment data to help customers.
  </Card>
</CardGroup>

***

## Before You Begin

<Info>
  All fitment operations require an integration API key with the `FITMENT_MANAGE` permission.
</Info>

| Requirement                 | Where to find it                             |
| --------------------------- | -------------------------------------------- |
| Integration API Key         | Dashboard → Settings → API Keys              |
| `FITMENT_MANAGE` permission | Enabled when creating or editing the API key |

All fitment mutations and queries are served at `https://api.withremark.com/graphql` and authenticate via the `X-Vendor-Api-Key` header.

***

## Facets

Facets define the dimensions used to describe a fitment target. For vehicles, typical facets are **Year**, **Make**, and **Model** — but you can define whatever dimensions fit your catalog.

Facets are ordered by `position`. This ordering determines the cascading selection flow in the AI assistant (e.g., Year first, then Make, then Model).

### Create a Facet

```graphql theme={null}
mutation CreateFitmentFacet($input: CreateFitmentFacetInput!) {
  createFitmentFacet(input: $input) {
    id
    name
    slug
    position
  }
}
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.withremark.com/graphql \
    -H "Content-Type: application/json" \
    -H "X-Vendor-Api-Key: rmrk_your_api_key" \
    -d '{
      "query": "mutation CreateFitmentFacet($input: CreateFitmentFacetInput!) { createFitmentFacet(input: $input) { id name slug position } }",
      "variables": {
        "input": { "name": "Year", "slug": "year", "position": 0 }
      }
    }'
  ```
</CodeGroup>

| Field      | Type   | Required | Description                                                                                  |
| ---------- | ------ | -------- | -------------------------------------------------------------------------------------------- |
| `name`     | String | Yes      | Display name (max 255 chars)                                                                 |
| `slug`     | String | Yes      | URL-safe identifier. Lowercase alphanumeric with hyphens (e.g., `year`, `make`, `sub-model`) |
| `position` | Int    | Yes      | Ordering position (0-indexed). Controls the cascading selection order                        |

### List Facets

```graphql theme={null}
query FitmentFacets {
  fitmentFacets {
    id
    name
    slug
    position
  }
}
```

Returns all facets for the authenticated vendor, ordered by `position`.

### Update a Facet

```graphql theme={null}
mutation UpdateFitmentFacet($id: ID!, $input: UpdateFitmentFacetInput!) {
  updateFitmentFacet(id: $id, input: $input) {
    id
    name
    position
  }
}
```

All `input` fields are optional — only include what you want to change.

### Delete a Facet

```graphql theme={null}
mutation DeleteFitmentFacet($id: ID!) {
  deleteFitmentFacet(id: $id)
}
```

<Warning>
  Deleting a facet cascades — all associated facet values on targets are removed.
</Warning>

***

## Targets

A fitment target represents a specific configuration (e.g., "2024 Honda CRF450R"). Each target has an `externalId` you control and a set of facet values keyed by facet slug.

### Create a Target

```graphql theme={null}
mutation CreateFitmentTarget($input: CreateFitmentTargetInput!) {
  createFitmentTarget(input: $input) {
    id
    externalId
    label
    facetValues
  }
}
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.withremark.com/graphql \
    -H "Content-Type: application/json" \
    -H "X-Vendor-Api-Key: rmrk_your_api_key" \
    -d '{
      "query": "mutation CreateFitmentTarget($input: CreateFitmentTargetInput!) { createFitmentTarget(input: $input) { id externalId label facetValues } }",
      "variables": {
        "input": {
          "externalId": "2024-honda-crf450r",
          "facetValues": { "year": "2024", "make": "Honda", "model": "CRF450R" }
        }
      }
    }'
  ```
</CodeGroup>

| Field         | Type   | Required | Description                                                                             |
| ------------- | ------ | -------- | --------------------------------------------------------------------------------------- |
| `externalId`  | String | Yes      | Your unique identifier for this target (max 255 chars)                                  |
| `label`       | String | No       | Display label. Auto-generated from facet values if omitted (e.g., "2024 Honda CRF450R") |
| `facetValues` | JSON   | Yes      | Object keyed by facet slug (e.g., `{"year": "2024", "make": "Honda"}`)                  |

### Bulk Upsert Targets

For loading large sets of targets (up to 5,000 per request), use `bulkUpsertFitmentTargets`. Targets are matched by `externalId` — existing targets are updated, new ones are created.

```graphql theme={null}
mutation BulkUpsertFitmentTargets($input: BulkUpsertFitmentTargetsInput!) {
  bulkUpsertFitmentTargets(input: $input) {
    created
    updated
    total
  }
}
```

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.withremark.com/graphql \
    -H "Content-Type: application/json" \
    -H "X-Vendor-Api-Key: rmrk_your_api_key" \
    -d '{
      "query": "mutation BulkUpsertFitmentTargets($input: BulkUpsertFitmentTargetsInput!) { bulkUpsertFitmentTargets(input: $input) { created updated total } }",
      "variables": {
        "input": {
          "targets": [
            { "externalId": "2024-honda-crf450r", "facetValues": { "year": "2024", "make": "Honda", "model": "CRF450R" } },
            { "externalId": "2024-honda-crf450rx", "facetValues": { "year": "2024", "make": "Honda", "model": "CRF450RX" } },
            { "externalId": "2023-yamaha-yz250f", "facetValues": { "year": "2023", "make": "Yamaha", "model": "YZ250F" } }
          ]
        }
      }
    }'
  ```
</CodeGroup>

Response:

```json theme={null}
{
  "data": {
    "bulkUpsertFitmentTargets": { "created": 3, "updated": 0, "total": 3 }
  }
}
```

### List Targets

```graphql theme={null}
query FitmentTargets($input: FitmentTargetsFilterInput) {
  fitmentTargets(input: $input) {
    targets {
      id
      externalId
      label
      facetValues
    }
    nextCursor
  }
}
```

Supports cursor-based pagination and filtering by facet values:

| Input Field   | Type | Description                                                              |
| ------------- | ---- | ------------------------------------------------------------------------ |
| `limit`       | Int  | Results per page (1–500, default 100)                                    |
| `cursor`      | ID   | Cursor for the next page (from the previous response's `nextCursor`)     |
| `facetValues` | JSON | Filter by exact facet values (e.g., `{"year": "2024", "make": "Honda"}`) |

### Update a Target

```graphql theme={null}
mutation UpdateFitmentTarget($id: ID!, $input: UpdateFitmentTargetInput!) {
  updateFitmentTarget(id: $id, input: $input) {
    id
    label
    facetValues
  }
}
```

* Omit `label` to leave it unchanged (it auto-regenerates if `facetValues` is updated).
* Pass `label: null` to clear it.
* Pass `label: "..."` to override with a specific value.

### Delete a Target

```graphql theme={null}
mutation DeleteFitmentTarget($id: ID!) {
  deleteFitmentTarget(id: $id)
}
```

<Warning>
  Deleting a target removes all product and variant associations.
</Warning>

***

## Linking Products

Associate fitment targets with products by including `fitmentTargetExternalIds` in your [product import](/guides/product-import) payload. This works with both SFTP and direct API imports.

```json theme={null}
{
  "externalId": "brake-pad-001",
  "name": "Performance Brake Pads",
  "brandName": "StopTech",
  "externalUrl": "https://store.example.com/products/brake-pad-001",
  "fitmentTargetExternalIds": [
    "2024-honda-crf450r",
    "2023-honda-crf450r"
  ],
  "variants": [
    {
      "externalId": "bp-001-organic",
      "name": "Organic Compound",
      "sku": "ST-BP-ORG-001",
      "fitmentTargetExternalIds": ["2024-honda-crf450r"],
      "prices": [{ "price": 49.99, "currency": "USD" }]
    }
  ]
}
```

Fitment can be set at the product level, variant level, or both:

* **Product-level**: All variants inherit compatibility with the listed targets.
* **Variant-level**: Specific variants are compatible with specific targets (e.g., a left-side brake pad only fits certain bikes).

<Note>
  External IDs that don't match existing fitment targets are skipped with a warning — they won't cause the import to fail. Create your fitment targets before importing products.
</Note>

***

## AI Assistant Behavior

Once fitment facets and targets are configured, Remark's AI assistant automatically gains the ability to help customers find compatible products.

### How it works

1. **Freeform matching**: The assistant passes whatever the customer has shared ("my 24 Chevy Silverado 1500") to the fitment tool in a single call. The tool resolves each freeform value to the catalog's canonical value, handling aliases and formatting differences.

2. **Targeted disambiguation**: If a value is ambiguous or missing, the tool returns the relevant facet and a short list of candidates for the assistant to clarify with the customer — one round-trip at a time.

3. **Target resolution**: Once all facets match, the tool returns the resolved fitment target, which is remembered for the rest of the conversation.

4. **Filtered search**: Product searches automatically filter to parts compatible with the customer's vehicle. The assistant mentions the active vehicle filter in results.

### Example conversation

> **Customer**: I need brake pads for my 2024 Honda CRF450R
>
> **Assistant**: Got it — I'll filter results for your 2024 Honda CRF450R. Here are the brake pads that fit your bike: ...

Disambiguation only happens when needed:

> **Customer**: brake pads for a 2024 Honda
>
> **Assistant**: Which model? Common options: CRF450R, CRF450RX, CRF250R.
>
> **Customer**: CRF450R
>
> **Assistant**: Filtering for your 2024 Honda CRF450R: ...

***

## Setup Checklist

<Steps>
  <Step title="Create facets">
    Define your fitment dimensions (e.g., Year, Make, Model) with the correct ordering.
  </Step>

  <Step title="Load targets">
    Bulk upsert your fitment targets with facet values. For large catalogs, batch into requests of up to 5,000 targets each.
  </Step>

  <Step title="Link products">
    Include `fitmentTargetExternalIds` in your product import payloads.
  </Step>

  <Step title="Test">
    Start a conversation with Remark's AI assistant and verify the vehicle resolution and filtered search results.
  </Step>
</Steps>

***

## Need Help?

Contact [support@remark.ai](mailto:support@remark.ai) for assistance with fitment setup.
