Keep the portfolio in sync

Push every portfolio change as it happens and expose a URL CLC can read, so collateral value, and the margin call price with it, is never stale.

CLC prices collateral from the portfolio you report. A portfolio we do not know about is a margin call price that is wrong, so this starts before you request a facility and keeps running for as long as one is open.

Scopes borrower:write to push and configure, and borrower:read to read the configuration back

CLC takes the portfolio two ways and you owe us both. You push every change the moment it happens, and you expose a URL we can read on our own, so one missed push does not leave us stale.

1. Push every change

Send this on every portfolio change, for example:

  • a deposit
  • a withdrawal
  • a trade
  • a transfer between accounts

Send it as the change happens, not on a schedule.

Two things decide whether this works:

  • It is a full replace, not a delta. An asset you leave out is read as zero, so always send the complete holdings.
  • as_of is when the portfolio was true on your side, not when you sent it. CLC keeps the newest as_of it has seen, so updates that arrive out of order cannot roll the portfolio backwards.
curl -X PUT https://api.clc.solutions/v1/borrowers/bor_9f2c/portfolio \
  -H "X-CLC-Key-Id: $CLC_KEY_ID" \
  -H "X-CLC-Timestamp: $CLC_TIMESTAMP" \
  -H "X-CLC-Signature: $CLC_SIGNATURE" \
  -d '{
    "as_of": "2026-07-21T14:30:00Z",
    "positions": [
      {
        "asset": "BTC",
        "quantity": "0.5"
      },
      {
        "asset": "ETH",
        "quantity": "3.0"
      }
    ]
  }'
{
  "borrower_id": "bor_9f2c",
  "as_of": "2026-07-21T14:30:00Z",
  "positions": [
    {
      "asset": "BTC",
      "quantity": "0.5"
    },
    {
      "asset": "ETH",
      "quantity": "3.0"
    }
  ],
  "applied": true
}

There is no Idempotency-Key here on purpose: a full replace ordered by as_of is already safe to repeat, and this endpoint fires far too often to make you mint a key each time.

2. Read back what CLC kept

When an update arrives with an as_of older than the one CLC already holds, nothing changes and the response says so. That is the normal outcome of two updates crossing on the wire, not an error. The state below is the one that was kept.

{
  "borrower_id": "bor_9f2c",
  "as_of": "2026-07-21T14:31:45Z",
  "positions": [
    {
      "asset": "BTC",
      "quantity": "0.4"
    }
  ],
  "applied": false
}

3. Expose a URL CLC can read

Pushes get lost: your process restarts, our endpoint is briefly unreachable. So CLC also reads portfolios on its own, and for that you point us at an endpoint of yours.

The URL must be HTTPS and must contain the {borrower_id} placeholder. CLC substitutes the borrower's id on each call, so you have to store our bor_… id next to the portfolio on your side.

If your endpoint needs authentication, set header_name and header_value. Sending a name without a value is rejected. CLC sends that header on every call, and the value is write-only, so it is never returned.

curl -X PUT https://api.clc.solutions/v1/portfolio-source \
  -H "X-CLC-Key-Id: $CLC_KEY_ID" \
  -H "X-CLC-Timestamp: $CLC_TIMESTAMP" \
  -H "X-CLC-Signature: $CLC_SIGNATURE" \
  -d '{
    "url": "https://broker.example/clc/borrower-portfolio?borrower_id={borrower_id}",
    "header_name": "X-Broker-Token",
    "header_value": "s3cr3t"
  }'
{
  "url": "https://broker.example/clc/borrower-portfolio?borrower_id={borrower_id}",
  "header_name": "X-Broker-Token"
}

4. Serve what CLC asks for

CLC issues a plain GET with the placeholder filled in and your header attached:

GET /clc/borrower-portfolio?borrower_id=bor_9f2c
Host: broker.example
X-Broker-Token: s3cr3t

Answer 200 with exactly the body you would have sent in step 1, meaning as_of plus the complete positions:

{
  "as_of": "2026-07-21T14:30:00Z",
  "positions": [
    {
      "asset": "BTC",
      "quantity": "0.5"
    },
    {
      "asset": "ETH",
      "quantity": "3.0"
    }
  ]
}

5. Check what is configured

header_value is never returned. header_name coming back tells you a value is stored against it.

curl -X GET https://api.clc.solutions/v1/portfolio-source \
  -H "X-CLC-Key-Id: $CLC_KEY_ID" \
  -H "X-CLC-Timestamp: $CLC_TIMESTAMP" \
  -H "X-CLC-Signature: $CLC_SIGNATURE"
{
  "url": "https://broker.example/clc/borrower-portfolio?borrower_id={borrower_id}",
  "header_name": "X-Broker-Token"
}

Did this page help you?