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

# Route Templates

> Save a custom route under a name and reuse it

A route template is a [custom route](https://dev-docs.multihopper.com/guides/custom-routes.md) saved under a name. Its `route.hops` can be
reused with `routeTemplateId` on [create](https://dev-docs.multihopper.com/api-reference/transfers/create.md) and
[estimate](https://dev-docs.multihopper.com/api-reference/transfers/estimate.md), in place of `route`. Templates are private to your
integration.

* **Transfers copy the hops.** Editing or deleting a template never changes a transfer already
  created from it.
* **Bundle hops are drawn again for each transfer**, so two transfers from one template can pass
  through different library wallets.
* **A template works one way or both.** The rules differ for one recipient and for several
  destinations (see [Rules](https://dev-docs.multihopper.com/guides/custom-routes.md#rules)). A template is saved if it works at least one
  way. `usableFor` says which, and `problems` says why not. Both are checked again on every read.
* Up to **100 templates** per integration. Names are unique within your integration.

`POST`, `PATCH` and `DELETE` require an `Idempotency-Key` header, like every mutation.

## Endpoints

| Method | Path | |
| - | - | - |
| `POST` | `/api/v1/route-templates` | Save a template: `{ name, description?, route: { hops } }` |
| `GET` | `/api/v1/route-templates` | List your templates, by name. `?name=` finds one by its exact name |
| `GET` | `/api/v1/route-templates/{templateId}` | Get one |
| `PATCH` | `/api/v1/route-templates/{templateId}` | Change its `name`, `description` or `route` (send at least one) |
| `DELETE` | `/api/v1/route-templates/{templateId}` | Delete it |

## Request body (POST)

**name** `string` *required*

1–64 characters: letters, digits, spaces, `.`, `_` or `-`, starting with a letter or digit. Unique
in your integration (`MH_022`).

**description** `string | null`

Up to 500 characters, for example what the route is for.

**route** `object` *required*

`{ "hops": [...] }`, exactly as on [create](https://dev-docs.multihopper.com/api-reference/transfers/create.md): each hop
`{ "wallet", "waitSeconds" }` or `{ "bundle", "waitSeconds" }`.

## Response

**id** `integer`

Pass it as `routeTemplateId`.

**name** `string`

**description** `string | null`

**route** `object`

`{ hops }` as saved, bundles unresolved.

**arrivalSeconds** `integer`

How long the route takes: the sum of its waits.

**usableFor** `object`

`{ recipientWallet: boolean, destinations: boolean }`.

**problems** `object`

For each way the template cannot be used, the `MH_018` messages it would get. `{}` when both work.

**createdAt** `string`

**updatedAt** `string`

## Errors

| Code | When |
| - | - |
| `MH_018` | The hops make a route neither way. The message lists the problems, marking those that apply to only one way. |
| `MH_021` | Your integration has no template with this id (404). Also returned by create and estimate for an unknown `routeTemplateId`. |
| `MH_022` | The name is taken in your integration (409). |
| `MH_023` | Your integration already has 100 templates. |

```bash Save theme={null}
curl -X POST https://multihopper.com/api/v1/route-templates \
  -H "x-api-key: $MH_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "name": "exchange-hop",
        "description": "Through one exchange and one KOL wallet",
        "route": { "hops": [
          { "bundle": "cex", "waitSeconds": 120 },
          { "wallet": "DQTf1yf1YM4B48PqJyQ53SEWGDM6ib4YBV7P3wm2MCxj", "waitSeconds": 300 },
          { "bundle": "kol", "waitSeconds": 600 } ] } }'
```

```bash Use theme={null}
curl -X POST https://multihopper.com/api/v1/transfers \
  -H "x-api-key: $MH_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{ "tokenMint": "So11111111111111111111111111111111111111112",
        "amountRaw": "1000000000", "amountTokens": "1", "tokenDecimals": 9,
        "sourceOwner": "<your wallet>",
        "recipientWallet": "7pBqizvE8vQZ29F49NWSu9cho3s7M9SqJyNN1UoQyQ2u",
        "routeTemplateId": 5 }'
```

```json 200 theme={null}
{
  "id": 5,
  "name": "exchange-hop",
  "description": "Through one exchange and one KOL wallet",
  "route": {
    "hops": [
      { "bundle": "cex", "waitSeconds": 120 },
      { "wallet": "DQTf1yf1YM4B48PqJyQ53SEWGDM6ib4YBV7P3wm2MCxj", "waitSeconds": 300 },
      { "bundle": "kol", "waitSeconds": 600 }
    ]
  },
  "arrivalSeconds": 1020,
  "usableFor": { "recipientWallet": true, "destinations": true },
  "problems": {},
  "createdAt": "2026-10-21T09:00:00.000Z",
  "updatedAt": "2026-10-21T09:00:00.000Z"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.