# Accounts & Funding

> REST API for brokers to onboard end-user clients, open trading accounts, and move funds. Used by CRMs, in-house back-office tools, and client cabinet/portal integrations.

Source: /admin/accounts-funding

**You can:**

- Onboard a client (create a profile, attach trading accounts).
- Deposit, withdraw, and post balance adjustments.
- Read orders, positions, portfolios, and deal history.
- Issue end-user access tokens so clients can call the [Trader API](/trader).

This API does **not** configure platform-level objects (account groups, symbols, margin/commission templates). Those are managed by your Helio admins through the full Admin API.

## Prerequisites

Before you start, make sure you have:

- The **Helio admin endpoint** for your environment (provided by your Helio contact).
- Either **(a)** a back-office username + password, or **(b)** a long-lived admin access token.
- Your outbound **IP whitelisted** by Helio operations — non-whitelisted requests are rejected.

## Authentication

Every request to this API must include a bearer admin token in the `Authorization` header:

```http
Authorization: Bearer <ADMIN_ACCESS_TOKEN>
```

Tokens are valid for **30 days**. Refresh by calling [Admin Login](/admin/accounts-funding/sessions/accounts-service_-user-login) again before expiry, or whenever a request returns `401 Unauthorized`.

### Obtain a token

<Tab value="cURL">
```bash
curl -X POST "$HELIO_ADMIN_URL/user/login" \
  -H "Content-Type: application/json" \
  -d '{"username": "ops@yourbroker.com", "password": "***"}'
# => { "token": "eyJhbGciOi..." }
```
</Tab>
<Tab value="JavaScript">
```js
const res = await fetch(`${process.env.HELIO_ADMIN_URL}/user/login`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: 'ops@yourbroker.com', password: '***' }),
})
const { token } = await res.json()
```
</Tab>
<Tab value="Python">
```python

res = requests.post(
    f"{os.environ['HELIO_ADMIN_URL']}/user/login",
    json={"username": "ops@yourbroker.com", "password": "***"},
)
token = res.json()["token"]
```
</Tab>
<Tab value="Go">
```go
body, _ := json.Marshal(map[string]string{
    "username": "ops@yourbroker.com",
    "password": "***",
})
res, _ := http.Post(os.Getenv("HELIO_ADMIN_URL")+"/user/login",
    "application/json", bytes.NewReader(body))
var out struct{ Token string `json:"token"` }
json.NewDecoder(res.Body).Decode(&out)
```
</Tab>

### Reuse the token

Cache the token and pass it on every subsequent call:

<Tab value="cURL">
```bash
curl "$HELIO_ADMIN_URL/account-groups" \
  -H "Authorization: Bearer $TOKEN"
```
</Tab>
<Tab value="JavaScript">
```js
const res = await fetch(`${HELIO_ADMIN_URL}/account-groups`, {
  headers: { Authorization: `Bearer ${token}` },
})
```
</Tab>
<Tab value="Python">
```python
res = requests.get(
    f"{HELIO_ADMIN_URL}/account-groups",
    headers={"Authorization": f"Bearer {token}"},
)
```
</Tab>
<Tab value="Go">
```go
req, _ := http.NewRequest("GET", HELIO_ADMIN_URL+"/account-groups", nil)
req.Header.Set("Authorization", "Bearer "+token)
res, _ := http.DefaultClient.Do(req)
```
</Tab>

All requests must originate from a whitelisted IP. Calls from any other source are rejected at the edge before reaching this API.

## Onboard a client

Onboarding a new client takes four calls. Keep the IDs returned at each step — later steps need them.

<Step>
### Fetch reference data

Currencies and account groups are configured by your Helio admins. Read what's available in your environment before creating accounts.

- **`GET /options/currencies`** &nbsp;→&nbsp; the currencies an account can be denominated in.
- **`GET /account-groups`** &nbsp;→&nbsp; the account groups a new account can be assigned to. Note each group's `id`, whether it's `isDemo`, and any `description` your admins have provided.
</Step>

<Step>
### Create a client profile

A profile represents one end-user. One profile can own many trading accounts (e.g. one per currency or strategy).

**`POST /profiles`** &nbsp;→&nbsp; capture the returned `profile.id`.

</Step>

<Step>
### Create a trading account

**`POST /accounts`** with `profileId`, `currency`, and `groupId` from the previous steps.

The account's **currency is fixed at creation** and cannot be changed. The **`spreadBetting` flag is also immutable** after creation.
</Step>

<Step>
### (Optional) Fund the account

Credit the opening balance with **`POST /accounts/{accountId}/deposit`**. Use `withdraw` to debit, or `BalanceTransactionCreate` for adjustments.
</Step>

### End-to-end example

<Tab value="JavaScript">
```js
const base = process.env.HELIO_ADMIN_URL
const headers = (token) => ({
  'Content-Type': 'application/json',
  Authorization: `Bearer ${token}`,
})

// 1. Login
const { token } = await fetch(`${base}/user/login`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ username: 'ops@yourbroker.com', password: '***' }),
}).then((r) => r.json())

// 2. Reference data
const groups = await fetch(`${base}/account-groups`, { headers: headers(token) })
  .then((r) => r.json())
const liveGroup = groups.groups.find((g) => !g.isDemo)

// 3. Create profile
const profile = await fetch(`${base}/profiles`, {
  method: 'POST',
  headers: headers(token),
  body: JSON.stringify({
    email: 'jane.doe@example.com',
    firstName: 'Jane',
    lastName: 'Doe',
  }),
}).then((r) => r.json())

// 4. Create account
const { account } = await fetch(`${base}/accounts`, {
  method: 'POST',
  headers: headers(token),
  body: JSON.stringify({
    profileId: profile.id,
    currency: 'USD',
    groupId: liveGroup.id,
  }),
}).then((r) => r.json())

// 5. Deposit opening balance
await fetch(`${base}/accounts/${account.id}/deposit`, {
  method: 'POST',
  headers: headers(token),
  body: JSON.stringify({ amount: '10000', comment: 'Opening deposit' }),
})
```
</Tab>
<Tab value="Python">
```python

base = os.environ["HELIO_ADMIN_URL"]

# 1. Login
token = requests.post(
    f"{base}/user/login",
    json={"username": "ops@yourbroker.com", "password": "***"},
).json()["token"]
auth = {"Authorization": f"Bearer {token}"}

# 2. Reference data
groups = requests.get(f"{base}/account-groups", headers=auth).json()["groups"]
live_group = next(g for g in groups if not g.get("isDemo"))

# 3. Create profile
profile = requests.post(
    f"{base}/profiles",
    headers=auth,
    json={
        "email": "jane.doe@example.com",
        "firstName": "Jane",
        "lastName": "Doe",
    },
).json()

# 4. Create account
account = requests.post(
    f"{base}/accounts",
    headers=auth,
    json={
        "profileId": profile["id"],
        "currency": "USD",
        "groupId": live_group["id"],
    },
).json()["account"]

# 5. Deposit opening balance
requests.post(
    f"{base}/accounts/{account['id']}/deposit",
    headers=auth,
    json={"amount": "10000", "comment": "Opening deposit"},
)
```
</Tab>

## Key concepts

<Card title="Profiles vs accounts">
A **profile** is the end-user (one per client). An **account** is a trading book under that profile. One profile can own many accounts — for example, one per currency or one live and one demo.
</Card>

<Card title="Account groups">
A group is a pre-configured bundle of trading rules — margin call / stop-out levels, margin calculation type, swap-free flag, demo vs live, and the linked symbol profile that determines which symbols the account can trade. Groups are **read-only here**: brokers select an existing group when creating an account, but groups themselves (and the symbols, margin templates, and commission templates they reference) are configured by your Helio admins outside this API.
</Card>

<Card title="Currencies & immutables">
An account's `currency` and `spreadBetting` flag are fixed at creation and cannot be changed later. Choose deliberately. Other settings (group, leverage cap, statement emails) can be updated via [Update Account](/admin/accounts-funding/accounts/accounts-service_-account-update).
</Card>

<Card title="End-user trading">
This API does not place orders. Once a client has a profile and account, issue them a Trader API token via [Create Session](/admin/accounts-funding/sessions/accounts-service_-client-login) (`POST /trade/login`) — they then trade against the [Trader API](/trader) directly.
</Card>

## Next steps

  <Card href="/admin/accounts-funding/funding/accounts-service_-deposit-transaction" title="Deposit funds">
    Credit a trading account.
  </Card>
  <Card href="/admin/accounts-funding/funding/accounts-service_-withdraw-transaction" title="Withdraw funds">
    Debit a trading account.
  </Card>
  <Card href="/admin/accounts-funding/trading/accounts-service_-order-history" title="Order history">
    Historical orders for an account over a date range.
  </Card>
  <Card href="/admin/accounts-funding/trading/accounts-service_-position-history" title="Position history">
    Historical positions for an account over a date range.
  </Card>
