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

# Partner Launch & Conformance

> Provision partner environments, validate known routes, and agree production service targets

Use this checklist with the [Aggregator Integration](/guides/aggregator-integration) guide before enabling AKKA in production routing.

## Environment provisioning

AKKA issues separate credentials per partner and environment. Request the following from the AKKA team:

* A staging base URL and staging API key.
* A production API key with an agreed request-rate and burst limit.
* Source display name, icon, support channel, and incident escalation contacts.
* Funded test payer addresses controlled by the partner. Never share private keys with AKKA.

Keys must be supplied through the `apikey` header and stored only in a backend secret manager. Staging and production keys must not be interchangeable. The API gateway must authenticate the key, remove any client-supplied `x-akka-partner-id` and `x-akka-gateway-auth`, then inject the canonical partner ID and the backend-only gateway secret before forwarding. The backend ignores partner identity unless `x-akka-gateway-auth` matches `PARTNER_GATEWAY_SECRET` using a timing-safe comparison.

## Known conformance pairs

These verified token pairs exercise the three transaction shapes. Amounts are examples in smallest units; the payer must also hold native gas.

| Chain              | Case            | Source                                             | Destination                                       | Example amount       |
| ------------------ | --------------- | -------------------------------------------------- | ------------------------------------------------- | -------------------- |
| Ethereum (`1`)     | ERC-20 → ERC-20 | WETH `0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2`  | USDC `0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48` | `10000000000000000`  |
| HyperEVM (`999`)   | Native → ERC-20 | `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`       | USDC `0xb88339cb7199b77e23db6e890353e22632ba630f` | `100000000000000000` |
| HyperEVM (`999`)   | ERC-20 → native | WHYPE `0x5555555555555555555555555555555555555555` | `0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee`      | `100000000000000000` |
| Robinhood (`4663`) | ERC-20 → ERC-20 | WETH `0x0bd7d308f8e1639fab988df18a8011f41eacad73`  | USDG `0x5fc5360d0400a0fd4f2af552add042d716f1d168` | `10000000000000000`  |

Route availability is dynamic. A no-route result is not a conformance failure unless AKKA and the partner have designated the case as funded and continuously monitored.

## Automated conformance runner

Use the standalone Node.js script below; access to the private AKKA repository is not required. When manually run, it always validates the active-chain and liquidity-source discovery responses. It validates an executable quote only when every required quote variable is provided. The script requests transaction data but never signs or broadcasts a transaction.

Copy this into a local file named `partner-conformance.js`:

<Accordion title="Show partner-conformance.js">
  ```javascript theme={null}
  const assert = require('node:assert/strict');

  const baseUrl = process.env.PARTNER_BASE_URL;
  const apiKey = process.env.PARTNER_API_KEY;

  if (!baseUrl || !apiKey) {
    throw new Error('Set PARTNER_BASE_URL and PARTNER_API_KEY');
  }

  async function get(path, params = {}) {
    const url = new URL(path, baseUrl);
    for (const [key, value] of Object.entries(params)) {
      url.searchParams.set(key, value);
    }

    const response = await fetch(url, { headers: { apikey: apiKey } });
    const body = await response.json();
    assert.equal(
      response.ok,
      true,
      `${response.status}: ${JSON.stringify(body)}`,
    );
    return body;
  }

  async function main() {
    const chains = await get('/partner/v1/chains');
    assert.ok(Array.isArray(chains) && chains.length > 0, 'no active chains');

    for (const chain of chains) {
      assert.equal(typeof chain.chainId, 'number');
      assert.match(chain.routerAddress, /^0x[0-9a-fA-F]{40}$/);
      const sources = await get(`/partner/v1/${chain.chainId}/sources`);
      assert.ok(Array.isArray(sources), 'sources must be an array');
    }

    const requiredQuoteVariables = [
      'PARTNER_CHAIN_ID',
      'PARTNER_SRC',
      'PARTNER_DST',
      'PARTNER_AMOUNT',
      'PARTNER_PAYER',
    ];

    if (requiredQuoteVariables.every((name) => process.env[name])) {
      const quote = await get(
        `/partner/v1/${process.env.PARTNER_CHAIN_ID}/quote`,
        {
          src: process.env.PARTNER_SRC,
          dst: process.env.PARTNER_DST,
          amount: process.env.PARTNER_AMOUNT,
          payer: process.env.PARTNER_PAYER,
          recipient: process.env.PARTNER_RECIPIENT || process.env.PARTNER_PAYER,
          slippage: process.env.PARTNER_SLIPPAGE || '1',
        },
      );

      assert.match(quote.quoteId, /^[0-9a-f-]{36}$/i);
      assert.ok(BigInt(quote.buyAmount) > 0n);
      assert.ok(BigInt(quote.minAmountOut) > 0n);
      assert.match(quote.tx.to, /^0x[0-9a-fA-F]{40}$/);
      assert.match(quote.tx.data, /^0x[0-9a-fA-F]+$/);
      assert.ok(Array.isArray(quote.issues));
      assert.ok(quote.validation && quote.simulation);
    }

    console.log('Partner API conformance checks passed');
  }

  main().catch((error) => {
    console.error(error);
    process.exitCode = 1;
  });
  ```
</Accordion>

Run discovery-only validation with Node.js 18 or newer:

```bash theme={null}
PARTNER_BASE_URL=https://PARTNER_STAGING_URL \
PARTNER_API_KEY=YOUR_STAGING_KEY \
node partner-conformance.js
```

To validate a quote too, provide all required quote variables:

```bash theme={null}
PARTNER_BASE_URL=https://PARTNER_STAGING_URL \
PARTNER_API_KEY=YOUR_STAGING_KEY \
PARTNER_CHAIN_ID=1 \
PARTNER_SRC=0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2 \
PARTNER_DST=0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 \
PARTNER_AMOUNT=10000000000000000 \
PARTNER_PAYER=0xYOUR_FUNDED_TEST_PAYER \
PARTNER_RECIPIENT=0xYOUR_TEST_RECIPIENT \
node partner-conformance.js
```

Keep `PARTNER_API_KEY` in a backend environment or secret manager. Do not run this script in a browser or commit a real key to source control.

## Router verification

`GET /partner/v1/chains` returns the router address, explorer URL, contract version, operational status, and deployed-bytecode hash where the chain RPC is available. Partners should pin both the allowlisted address and reviewed code hash. A changed hash or `DEGRADED`/`DISABLED` status must pause new execution until reviewed. Deployment block and audit URLs are nullable until deployment records are linked to the public registry.

## Durable telemetry

The backend stores quote metadata in `partner_quote_telemetry` and partner-reported transaction lifecycle events in `partner_execution_telemetry`. By default it uses the `aggregator_health_monitor` schema on the `DATABASE_URL` server. Set `PARTNER_TELEMETRY_DATABASE_NAME` to change that schema, or `PARTNER_TELEMETRY_DATABASE_URL` when telemetry is hosted on a different MySQL server.

Apply `database/migrations/20260814_partner_telemetry.sql` with `npm run db:migrate:partner-telemetry` before enabling partner traffic. Telemetry writes fail open and are bounded by `PARTNER_TELEMETRY_WRITE_TIMEOUT_MS` (500 ms by default), so storage downtime never blocks quoting indefinitely. Operations must alert on `PartnerTelemetryService` write errors.

Stored fields support quote-to-execution analysis without retaining API keys, calldata, RFQ signatures, or complete responses. The migration includes a suggested 90-day cleanup policy; operations must schedule it according to the agreed privacy and retention policy.

## Pre-production test matrix

* Distinct payer and recipient, including a smart-contract payer.
* Native input, native output, and ERC-20-only routes.
* Zero and insufficient balance.
* Zero, exact, and unlimited allowance.
* No route, invalid token, invalid chain, and unsupported exact-output request.
* Expired advisory quote, price movement beyond slippage, and reverted simulation.
* `429`, timeout, and `5xx` retry behavior with jittered exponential backoff.
* Comparison of `buyAmount`, `minAmountOut`, simulated output, and actual receipt output.

## Service targets to agree before launch

The following are recommended negotiation targets, not an SLA unless included in a signed partner agreement:

| Metric                        | Recommended target                                 |
| ----------------------------- | -------------------------------------------------- |
| Discovery availability        | 99.95% monthly                                     |
| Executable quote availability | 99.9% monthly, excluding no-route responses        |
| Quote latency                 | p95 ≤ 2 seconds; p99 ≤ 5 seconds per enabled chain |
| Quote refresh window          | Use or refresh within the response `expiresAt`     |
| Incident acknowledgement      | 15 minutes for critical execution incidents        |
| Breaking API changes          | 30 days' notice and a versioned migration path     |

Partners should monitor latency, HTTP status, issue codes, simulation completeness, quote-to-simulation variance, quote-to-execution variance, and on-chain revert rate by chain and token pair.

## Circuit breakers and ownership

* `chains.is_active` is the chain-wide hard kill switch; disabled chains are rejected by every partner endpoint.
* Pool and maker blacklists remove known-bad liquidity from exact routing.
* Quarantine reporting removes confirmed on-chain pool failures and uses shorter treatment for empty liquidity.
* Source discovery is derived from active pools; a source disappears when operations deactivate its pools.
* Prometheus exports partner request count/outcome/latency plus route retry, floor-guard, and quarantine signals.

Alerting should automatically page operations. Changing chain activity, active-pool state, or managed blacklists remains an authenticated operations action rather than an unaudited in-process API mutation.

Recommended automatic policies:

* Mark a partner/chain `DEGRADED` when p95 latency or incomplete simulation exceeds the agreed window.
* Disable a source after a sustained execution-revert threshold, never from a single RFQ decline.
* Disable a chain when router code hash changes unexpectedly or exact quotes fail systemically.
* Require manual review to re-enable contract execution after a security-triggered disable.

## Compatibility fixtures and changes

The backend test suite contains a v1 partner response fixture and schema assertions. OpenAPI is regenerated from the Nest DTOs. CI should fail if required v1 fields, integer-string units, transaction semantics, or established enum values change. Breaking changes ship under `/partner/v2` with at least 30 days' notice unless an emergency security response requires immediate disablement.
