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

# Branding and your frontend

> What carries your brand, what carries Stableyard's, and which calls can run in your customer's browser.

Every screen you build on the API carries only your brand. A handful of steps run on pages and emails outside your product, and each one shows Stableyard, a verification provider, or both. Plan your flows around them rather than discover them in production.

## Two things you can brand

| Setting | Set it in | What it changes |
| - | - | - |
| App branding: `displayName`, `logoUrl`, `primaryColor` | The Partner Dashboard, **Configuration → Checkout branding**. Not the Partner API | Hosted checkout. Read back from `GET /v2/public/apps/{appId}/frontend-config` |
| Account display profile: `displayName`, `logoUrl` | `displayProfile` on `POST /v2/accounts`, or `PUT /v2/accounts/{accountId}/display-profile` | The recipient a payer sees for that account |

When an account has a display profile, hosted checkout names the account as the recipient and your app as the presenter: "Northwind via Your App". Without one, it shows your app branding alone. Unset app fields fall back to your app's name and a default colour.

```bash theme={null}
curl -X PUT https://staging-api-v2.stableyard.fi/v2/accounts/acct_123/display-profile \
  -u "$APP_ID:$APP_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Northwind Coffee",
    "logoUrl": "https://cdn.example.com/northwind.png",
    "expectedVersion": 0,
    "reason": "Merchant completed storefront setup"
  }'
```

* **`expectedVersion` guards concurrent edits.** Send `0` the first time, then the current `account.displayProfile.version`.
* **`reason` is required**, 10 to 500 characters, for the audit record.
* **`logoUrl` must be public HTTPS** with no embedded credentials, up to 2,048 characters. `displayName` is up to 120.
* **Changes reach future payments only.** Each payment keeps the `recipientDisplay` captured when it was created.

## Surfaces that are not yours

| Surface | When the customer meets it | What it shows | What you control |
| - | - | - | - |
| Hosted checkout, `checkout.paymentUrl` | Only if you send payers to it | Your branding or the recipient's in the header. "Secured by Stableyard" in the footer, and a menu with Stableyard's terms, privacy policy and website. Served from Stableyard's checkout domain | App branding and display profile. Not the domain, the footer or the menu |
| Email code and welcome email | Email verification under the `stableyard_email_otp` policy | Emails from Stableyard: "Verify your Stableyard account email", then "Welcome to Stableyard". Both name your app | Asserting the email yourself, where Stableyard enables it, sends neither |
| Identity verification, `verificationUrl` | Every individual's KYC | A page hosted by the verification provider | Nothing. There is no return URL |
| Bank access form, `complete_compliance` | Each capability an individual activates | Stableyard's wordmark, "Requested by" your app with its initials, and a code emailed by Stableyard: "Confirm your Stableyard compliance request" | Nothing |
| Business verification | Each business account | A page hosted by a provider | Nothing |
| Bank details | On-ramp deposit instructions | The bank and beneficiary name issued by the banking partner | Nothing. Show them exactly as returned |

<Note>
  The hosted pages and emails use your app's name as Stableyard has it on file, not your checkout branding. Neither carries your logo. There is no custom domain for hosted pages.
</Note>

Tell customers before each hand-off that the next page or email comes from Stableyard or a verification provider, and bring them back to a screen that reads the result. Hosted verification pages do not redirect to you, so that screen polls the resource or reacts to a webhook.

## Keep hosted checkout optional

You do not have to use hosted checkout. Create payments from your backend and render your own screens, either with the payment's client secret or with a client session. See [Build your own checkout](/payments/depositing-funds#build-your-own-checkout).

## Run calls from your customer's browser

Your app secret never leaves your backend. A browser or mobile app gets a short-lived client session bound to one account instead.

<Steps>
  <Step title="Your backend creates the session">
    ```bash theme={null}
    curl -X POST https://staging-api-v2.stableyard.fi/v2/client-sessions \
      -u "$APP_ID:$APP_SECRET" \
      -H "Content-Type: application/json" \
      -d '{ "externalUserId": "user_123", "expiresInSeconds": 600, "permissions": ["account:read", "deposits:read", "deposits:write"] }'
    ```

    Send `accountId` or `externalUserId`, not both. The account must already exist. `expiresInSeconds` runs from 60 to 3,600, default 600. Omitted `permissions` default to `account:read`.
  </Step>

  <Step title="Hand over the session token">
    Pass `clientSessionToken` to the browser. It can be exchanged once.
  </Step>

  <Step title="The browser exchanges it">
    `POST /v2/client/auth/exchange` with `{ "clientSessionToken": "…" }` returns an `accessToken` and the effective `permissions`.
  </Step>

  <Step title="The browser calls with the access token">
    `Authorization: Bearer <accessToken>` on `/v2/client/*`. An expired token returns `401 client_token_expired`: ask your backend for a new session.
  </Step>
</Steps>

| Client route | Permission | Does |
| - | - | - |
| `GET /v2/client/bootstrap` | `account:read` | The account bundle, recent activity and pending actions |
| `GET /v2/client/me/deposit-networks`, `GET /v2/client/me/deposit-addresses`, `GET /v2/client/me/deposits` | `deposits:read` | Read networks, addresses and deposits |
| `POST /v2/client/me/deposit-addresses`, `POST /v2/client/me/deposit-addresses/check` | `deposits:write` | Issue an address, or record a deposit by transaction hash |
| `GET /v2/client/me/payments/{paymentId}` | `payments:read` | Read one of the account's payments |
| `POST /v2/client/me/payments`, `POST /v2/client/me/payments/{paymentId}/confirm` | `payments:write` | Create a payment for the bound account, and confirm its outgoing action |

**Verification, bank accounts and on-ramp accounts have no client routes.** Email confirmation, KYC sessions, capability activation, bank linking, on-ramp issuance and deposit instructions all run from your backend. Your screen collects input and shows results; your backend makes the call.

Full rules for credentials and permissions are on [Authentication](/authentication).

<Card title="Next: Going live" icon="flag-checkered" href="/white-label/going-live">
  What Stableyard enables, and what changes between staging and production.
</Card>


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