Back to portfolio

Integration API Developer Portal

Explore a sample investment-data API, build a request, and inspect the response. The prototype demonstrates partner onboarding, scoped access, and integration support using fictional data.

An independent prototype. For my production work, see the ServiceTrade case study and developer portal.

Quickstart

Build your first request.

  1. 01

    Choose a dataset

    Start with positions. Run a request, then follow its next-page cursor.

  2. 02

    Filter and inspect

    Choose a portfolio, date, or response view. Run again to see the matching records.

  3. 03

    Investigate a failure

    Try a missing-scope or rate-limit scenario and inspect the response headers and recovery guidance.

Open request builder

Session checks

Evidence from your requests.

    Try the API

    Build, run, and inspect.

    Fictional records are fixed in 2026. Requests run locally in this page. The example host is a placeholder.

    Inclusive, from midnight UTC. Leave blank for all dates.

    Error scenarios use an illustrative X-Demo-Scenario header. No token is collected or issued.

    Last executed request

    Simulated response

    Partner journey

    From proposed integration to supported use.

    Illustrative process for a partner building a portfolio reporting integration. These steps describe review decisions, not an actual application or account.

    1. Evaluate the integration

      Review the partner's intended data use, client need, and fit with the product. Agree which organizations and datasets the integration may access.

    2. Define approved access

      Assign only the required read scopes. For server-to-server use, provision confidential client credentials through an approved process and keep the secret on the server.

    3. Validate behavior

      Test filtered reads, pagination, permission failures, and rate limits. The session checks above show which scenarios you have inspected in this prototype.

    4. Plan production support

      Review retry behavior, webhook verification, monitoring, ownership, and escalation contacts. Production access requires a separate review; completing the sample checks does not grant access.

    Authentication

    Server-to-server access with defined scopes.

    The fictional API uses OAuth 2.0 client credentials. Client ID and secret stay on the server. This grant does not use a browser redirect.

    Token request

    POST /oauth/token HTTP/1.1
    Host: api.example.test
    Authorization: Basic BASE64_CLIENT_ID_AND_SECRET
    Content-Type: application/x-www-form-urlencoded
    
    grant_type=client_credentials&scope=positions%3Aread

    Token response

    {
      "access_token": "EXAMPLE_ACCESS_TOKEN",
      "token_type": "Bearer",
      "expires_in": 3600,
      "scope": "positions:read"
    }

    The Basic value represents the encoded client ID and secret, not a real credential. See OAuth 2.0: client credentials. A token must contain the scope required by the endpoint.

    Endpoint reference

    Three connected datasets.

    GET

    /v1/positions

    Outstanding loan positions. Scope: positions:read. Details add issuer, asset, industry, and all-in rate.

    GET

    /v1/cashflows

    Dated cash activity linked by position_id. Scope: cashflows:read. Details include the related position. Positive amounts are receipts; funding is negative.

    GET

    /v1/events

    Cashflow change notifications linked by resource_id and position_id. Scope: events:read. Details include the changed cashflow record.

    Shared query parameters

    portfolio
    Optional. core-income, opportunistic-credit, or defensive-yield. Omit to include all portfolios.
    updated_since
    Optional. Inclusive midnight-UTC timestamp generated from the selected date. Filters the record's updated_at field, not the cashflow's scheduled date.
    include
    summary returns core fields; details adds the endpoint-specific fields above; events adds related event IDs, types, resource IDs, and timestamps to the summary. Stable record IDs remain in every view. Related records can precede the top-level updated-since filter.
    page_size / cursor
    Choose 2, 4, or 8 records per page. Results are ordered by updated_at, then id. Pass next_cursor unchanged to continue with the same filters and response view. A changed query requires a new first-page request.

    Webhooks

    Handle changes and repeated delivery.

    {
      "id": "evt_cash_AUR-112-2026-08-28-Interest",
      "type": "cashflow.updated",
      "resource_id": "cash_AUR-112-2026-08-28-Interest",
      "resource_type": "cashflow",
      "position_id": "pos_AUR-112",
      "updated_at": "2026-08-28T09:00:00Z"
    }
    • Verify the signature on the raw request body before parsing or accepting the event. Compare signatures in constant time and validate a signed timestamp to limit replay.
    • Persist the event ID and process duplicate deliveries safely. Confirm receipt after durable storage or queueing, then perform longer work asynchronously.
    • Retry temporary failures with bounded exponential backoff and jitter. Alert on exhausted retries rather than silently dropping events.

    For this fictional contract, delivery uses HMAC-SHA256 with a signed timestamp and a five-minute tolerance. Replay is available for 72 hours. These are example design choices, not ServiceTrade specifications. This prototype does not send or receive webhooks.

    For implementation patterns around signatures, duplicate events, and asynchronous processing, see Stripe's webhook guidance.

    Troubleshooting

    A reason and a next action.

    400Invalid date, option, or cursor. Correct the request or restart pagination.
    401Invalid or expired token. Obtain a new token and retry.
    403Insufficient scope. Confirm approved access and request a token with the required scope.
    429Request quota exhausted. Honor Retry-After, then retry with backoff. The sample header uses 60 seconds; it does not impose an actual wait.

    Use the Scenario control to inspect the 401, 403, and 429 examples. Return to Successful request to retry. See OAuth bearer-token error responses.