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

# Integrator Onboarding

> Create an integrator profile and API key through the wallet-signed onboarding flow.

## Overview

Integrator keys are created through a wallet-signed onboarding flow. The wallet
that applies becomes the owner wallet for the integrator profile and must also be
the fee-recipient wallet.

The flow is:

1. Build the application payload and its payload\_hash.
2. Call POST /integrators/nonce with action create\_integrator\_application.
3. Sign the exact message returned by the nonce endpoint with the owner wallet.
4. Submit the signed application to POST /integrators/applications.
5. Wait for Rialto approval if the application returns status: "pending".
6. After approval, request another nonce for create\_integrator\_api\_key, sign it,
   and call POST /integrators/api-keys.
7. Store the returned api\_key immediately. It is shown once. Later profile reads
   only return a masked key.

## Payload hash format

Mutable integrator actions require a payload\_hash:

```text theme={null}
keccak256("field_name=<byte length>:<value>\n" for each field, in order)
```

Use UTF-8 byte length for each value. Optional fields are encoded as `none` or
`some:<value>`.

## Endpoint: create integrator nonce

```http theme={null}
POST /integrators/nonce
```

Auth: public.

| Field | Description |
| - | - |
| chain\_id | Optional chain id. Use 4663 for Robinhood Chain. |
| wallet | Owner wallet that will sign. |
| action | One of create\_integrator\_application, create\_integrator\_api\_key, revoke\_integrator\_api\_key, or view\_integrator\_profile. |
| payload\_hash | Required for create and revoke actions. Not required for view\_integrator\_profile. |

Response includes message, nonce, issued\_at, and expiration\_time. Sign the exact
message string. Do not reconstruct it client-side.

## Endpoint: submit application

```http theme={null}
POST /integrators/applications
```

Auth: public.

| Field | Description |
| - | - |
| chain\_id | Optional chain id. |
| owner\_wallet | Wallet that owns the integrator profile. |
| display\_name | Human-readable partner or app name. |
| slug | Lowercase unique id, 3-64 chars, lowercase letters, digits, and hyphens only. |
| contact\_email | Required contact email. |
| telegram\_handle | Required Telegram handle. |
| app\_url | Required application URL. |
| application\_description | Required description, at most 200 words. |
| fee\_recipient | Wallet that receives integrator fees. Must equal owner\_wallet. |
| requested\_max\_fee\_bps | Max fee cap requested for this key, in basis points. |
| payload\_hash | Hash of the application fields. |
| nonce, issued\_at, expiration\_time, signature | Fields from /integrators/nonce plus the wallet signature. |

Example response:

```json theme={null}
{
  "integrator_id": 12,
  "slug": "example-wallet",
  "status": "pending",
  "message": "Application submitted for review."
}
```

If status is pending, the Rialto team will review your application. If approved,
the profile status becomes active and you can create an API key for it. If the
application response already returns active, you can create a key immediately.

## Endpoint: create API key

```http theme={null}
POST /integrators/api-keys
```

Auth: public.

| Field | Description |
| - | - |
| chain\_id | Optional chain id. |
| owner\_wallet | Integrator owner wallet. |
| integrator\_id | Numeric id returned by the application endpoint. |
| label | Human-readable key label. |
| payload\_hash | Hash of action, chain\_id, owner\_wallet, integrator\_id, and label. |
| nonce, issued\_at, expiration\_time, signature | Fields from /integrators/nonce plus the wallet signature. |

Response:

```json theme={null}
{
  "key_id": 34,
  "api_key": "rialto_live_example.redacted_secret",
  "masked_key": "rialto_live_example...cret",
  "prefix": "example",
  "scopes": ["quote:read", "swap:create", "swap:integrator"],
  "quote_rate_limit_per_minute": 6000,
  "swap_rate_limit_per_minute": 6000,
  "integrator_id": "example-wallet",
  "integrator_fee_recipient": "<taker_wallet_address>",
  "integrator_max_fee_bps": 50,
  "shown_once": true
}
```

The api\_key is shown only once at creation. Store it securely when this response
is returned. It cannot be retrieved again; /integrators/me only returns masked key
metadata.

## Profile and key management

| Endpoint | Purpose |
| - | - |
| POST /integrators/me | List profiles and masked keys for an owner wallet. |
| POST /integrators/api-keys/{key_id}/revoke | Revoke a key. Revoked keys are rejected by trading endpoints. |

Use action view\_integrator\_profile on /integrators/nonce, sign the returned
message, then submit owner\_wallet, nonce fields, and signature to /integrators/me.
Use action revoke\_integrator\_api\_key to revoke a key. Compute the payload\_hash
from owner\_wallet, integrator\_id, and key\_id.

## Python example

This example submits an application. If the application is already active, it
also creates an API key. If it is pending, save the returned `integrator_id` and
create the key after Rialto approves the application.

```bash theme={null}
python3 -m pip install requests eth-account eth-utils

export OWNER_PRIVATE_KEY='0xREDACTED_OWNER_PRIVATE_KEY'
python3 rialto_request_integrator_key.py
```

```python theme={null}
import os
import time

import requests
from eth_account import Account
from eth_account.messages import encode_defunct
from eth_utils import keccak

API_BASE = "https://rialto-trade-api.rialto.xyz"
CHAIN_ID = 4663
ACTION_CREATE_APPLICATION = "create_integrator_application"
ACTION_CREATE_API_KEY = "create_integrator_api_key"


def require_env(name):
    value = os.getenv(name)
    if not value:
        raise RuntimeError(f"missing {name}")
    return value


def payload_hash(fields):
    canonical = ""
    for key, value in fields:
        value = str(value)
        canonical += f"{key}={len(value.encode('utf-8'))}:{value}\n"
    return "0x" + keccak(canonical.encode("utf-8")).hex()


def sign_message(private_key, message):
    signed = Account.sign_message(encode_defunct(text=message), private_key)
    return "0x" + bytes(signed.signature).hex()


def nonce(owner, action, hash_value=None):
    body = {"chain_id": CHAIN_ID, "wallet": owner, "action": action}
    if hash_value is not None:
        body["payload_hash"] = hash_value
    response = requests.post(f"{API_BASE}/integrators/nonce", json=body, timeout=30)
    response.raise_for_status()
    return response.json()


private_key = require_env("OWNER_PRIVATE_KEY")
owner = Account.from_key(private_key).address.lower()
display_name = "Example Partner"
slug = f"example-partner-{int(time.time())}"
contact_email = "ops@example.com"
telegram_handle = "@example_ops"
app_url = "https://example.com"
application_description = "We want to route user swaps through Rialto."
fee_recipient = owner
requested_max_fee_bps = 50

app_hash = payload_hash(
    [
        ("action", ACTION_CREATE_APPLICATION),
        ("chain_id", CHAIN_ID),
        ("owner_wallet", owner),
        ("display_name", display_name),
        ("slug", slug),
        ("contact_email", contact_email),
        ("telegram_handle", telegram_handle),
        ("app_url", app_url),
        ("application_description", application_description),
        ("fee_recipient", fee_recipient),
        ("requested_max_fee_bps", requested_max_fee_bps),
    ]
)
app_nonce = nonce(owner, ACTION_CREATE_APPLICATION, app_hash)
app_body = {
    "chain_id": CHAIN_ID,
    "owner_wallet": owner,
    "display_name": display_name,
    "slug": slug,
    "contact_email": contact_email,
    "telegram_handle": telegram_handle,
    "app_url": app_url,
    "application_description": application_description,
    "fee_recipient": fee_recipient,
    "requested_max_fee_bps": requested_max_fee_bps,
    "payload_hash": app_hash,
    "nonce": app_nonce["nonce"],
    "issued_at": app_nonce["issued_at"],
    "expiration_time": app_nonce["expiration_time"],
    "signature": sign_message(private_key, app_nonce["message"]),
}
app_response = requests.post(
    f"{API_BASE}/integrators/applications",
    json=app_body,
    timeout=30,
)
app_response.raise_for_status()
application = app_response.json()
print("application:", application)

if application["status"] != "active":
    print("Application is pending approval. Create the API key after approval.")
    raise SystemExit(0)

integrator_id = application["integrator_id"]
label = "production-key"
key_hash = payload_hash(
    [
        ("action", ACTION_CREATE_API_KEY),
        ("chain_id", CHAIN_ID),
        ("owner_wallet", owner),
        ("integrator_id", integrator_id),
        ("label", label),
    ]
)
key_nonce = nonce(owner, ACTION_CREATE_API_KEY, key_hash)
key_body = {
    "chain_id": CHAIN_ID,
    "owner_wallet": owner,
    "integrator_id": integrator_id,
    "label": label,
    "payload_hash": key_hash,
    "nonce": key_nonce["nonce"],
    "issued_at": key_nonce["issued_at"],
    "expiration_time": key_nonce["expiration_time"],
    "signature": sign_message(private_key, key_nonce["message"]),
}
key_response = requests.post(
    f"{API_BASE}/integrators/api-keys",
    json=key_body,
    timeout=30,
)
key_response.raise_for_status()
created_key = key_response.json()
print("raw API key; store now:", created_key["api_key"])
print("masked key:", created_key["masked_key"])
```


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