Artham
ARTHAM

Webview Integration API Specification

Version 1.0  ·  September 2026

1. Overview

Artham's investment marketplace runs inside a webview hosted in your app. Your app renders a row of scheme cards from data Artham serves; when the user taps one, your app asks Artham for a URL and opens it in a webview. Everything after that point — scheme detail, onboarding, consent, mandate and investing — happens inside Artham's web application. Your app hosts the frame and nothing else.

How It Works

  1. Sign each request — every call carries an API key and an HMAC signature. There is no login step and no token to manage (Section 2).
  2. Fetch the schemes — one call returns every scheme available to your brokerage, with the summary fields your cards need (Section 4).
  3. Render cards in your app — your UI, your styling. Artham supplies the data, not the layout.
  4. Hand off on tap — the user taps a card, or your Artham header entry point. Your app calls Artham for a client-specific, pre-signed URL and opens it in a webview (Section 5).
  5. The journey continues in the webview — Artham handles the rest and signals back when the user exits (Section 6).

API Summary

#MethodEndpointPurpose
1GET/api/v1/partner/schemesAll schemes available to you, with card summary fieldsRequired
2POST/api/v1/partner/webview/linkPre-signed, client-specific webview URLRequired
Both endpoints are hosted by Artham. You do not build or host anything for this integration — you are the caller for every request in this document, and the webview itself is served by us.

Base URLs

Production:  https://api.artham.co
Sandbox:     https://distributor-api.artham.co

2. Authentication

Every request carries two headers: an API key that identifies your brokerage, and an HMAC signature that proves the request is yours and has not been altered. There is no login call, no token and no session to refresh.

HeaderDescriptionExample
X-Api-KeyStatic API key identifying your brokerage.artham_live_k8Fj2mNp...
X-SignatureHMAC-SHA256 of the request, computed with your Shared Secret. Proves the request is yours and untampered.a1b2c3d4... (64 hex chars)

Signature Computation

message = "{HTTP_METHOD}\n{path}\n{body}"

signature = HMAC-SHA256(key: SHARED_SECRET, message: message)
            → output as lowercase hex string
ComponentDescriptionExample
HTTP_METHODUppercase HTTP methodGET / POST
pathRequest path — no host, no query string/api/v1/partner/schemes
bodyRaw JSON request body, byte for byte as sent. Empty string "" for GET.{"clientCode":"PL889900"}
Sign the exact bytes you send. On API 2 the body is part of the message, so the JSON you sign and the JSON you transmit must be identical — same key order, same spacing, same encoding. Serialising once into a string, signing that string and sending that same string is the only reliable approach; re-serialising the object for the request will eventually produce a different byte sequence and a 401.
Sign the path only. Not the full https://… URL, and not the query string. This is the most common cause of a 401 on a first integration.

Worked Examples

Both examples use the demo secret below, so you can verify your implementation before your credentials arrive — the same inputs must produce the same digests.

secret = "artham_demo_secret_9f2b7c41e8d3"

# ─── API 1 — GET, no body ───────────────────────────────────
message   = "GET\n/api/v1/partner/schemes\n"
signature = 40f682d026b436293288648b8553927c398689f336b65f23136a081fe491c61d

# ─── API 2 — POST, body included ────────────────────────────
body      = {"clientCode":"PL889900","schemeCode":"ARTHAM-EQ-001"}
message   = "POST\n/api/v1/partner/webview/link\n" + body
signature = 065d4730e9fe6ed227f4902869d0415c2851b10cef40252339eb0fe9921a9db1

The API 1 call, against Sandbox:

curl -X GET "https://distributor-api.artham.co/api/v1/partner/schemes" \
  -H "X-Api-Key: <your API key>" \
  -H "X-Signature: <64-char lowercase hex>"

Credential Handling

The secret belongs on your server, never in the app. Both API calls must be made from your backend. A secret shipped inside a mobile binary can be extracted, and it would let anyone mint webview links for your clients.

Authentication Errors

HTTPerror.codeWhenWhat to do
401AUTH_REQUIREDX-Api-Key or X-Signature missingSend both headers
401AUTH_TOKEN_INVALIDUnknown API key, or the signature does not match the message we recomputedCheck you signed the path only, and — on API 2 — the exact body bytes
A 401 will not fix itself on a retry. Nothing about the signature is time-dependent, so a rejected request will be rejected again. Retry with backoff only on 5xx.

3. Error Handling

Every endpoint in this document answers with the same envelope.

Success

{
  "success": true,
  "data": { ... },
  "error": null
}

Error

{
  "success": false,
  "data": null,
  "error": {
    "code": "CLIENT_NOT_FOUND",
    "message": "No client found with code PL889900."
  }
}

HTTP Status Codes

StatusMeaning
200Success
400Invalid or missing request fields
401Missing or invalid key / signature — see Section 2
404Referenced scheme or client does not exist
422Business rule violation (e.g. scheme not available to your brokerage)
500Unexpected error on Artham's side — retry with backoff
Branch on the HTTP status and error.code, not on the message. The error.message text is written for humans reading logs and may change.

4. API 1 — Scheme List Required

Returns every scheme your brokerage is permitted to distribute, with the summary fields needed to render cards. Call it when your discovery screen loads, or cache it and refresh a few times a day.

GET /api/v1/partner/schemes Scheme summaries for your cards

Endpoint & Method

ItemValue
MethodGET
Path/api/v1/partner/schemes
AuthenticationX-Api-Key + X-Signature — see Section 2
Query parametersNone. The list is scoped to your brokerage by your API key.
PaginationNone. Scheme counts are in the tens, so the full set is returned in one response.

Response — 200 OK

{
  "success": true,
  "error": null,
  "data": {
    "count": 2,
    "returnsAsOf": "2026-08-31",
    "schemes": [
      {
        "schemeCode": "ARTHAM-EQ-001",
        "schemeName": "Quality Compounders",
        "advisorCode": "MRC",
        "advisorName": "Marcellus Investment Managers",
        "logoUrl": "https://artham-assets.s3.eu-north-1.amazonaws.com/advisors/mrc.png",
        "category": "Large Cap",
        "riskLevel": "Moderate",
        "shortDescription": "Twelve clean-accounting compounders, held through cycles.",
        "benchmark": "NIFTY 50 TRI",
        "minInvestment": 500000,
        "feePercent": 2.5,
        "aum": "1284500000.00",
        "inceptionDate": "2021-04-01",
        "constituentCount": 12,
        "returns": {
          "1m": "1.8400",
          "6m": "9.2100",
          "1y": "18.4200",
          "3y": "21.0500",
          "5y": null,
          "sinceInception": "19.7700"
        },
        "navSeries": [100.0, 102.4, 101.8, 106.2, 109.7, 108.3,
                      112.9, 116.4, 115.1, 119.8, 123.5, 126.1]
      }
    ]
  }
}

Scheme Fields

KeyTypeDescription
schemeCodestringThe identifier. Pass it back on API 2 to deep-link a card. Stable for the life of the scheme.
schemeNamestringDisplay name — the card title
advisorCodestringShort code of the SEBI-registered advisor managing the scheme
advisorNamestringAdvisor's display name — the card subtitle
logoUrlstring or nullAdvisor logo, HTTPS. null when none is set — fall back to initials.
categorystringFree-text grouping, e.g. "Large Cap", "Momentum". Use it for filter chips; do not hard-code the set.
riskLevelstring"Low", "Moderate" or "High"
shortDescriptionstringOne-line thesis, ~120 characters. Written to fit a card.
benchmarkstringBenchmark index name
minInvestmentintegerMinimum first cheque, whole rupees
feePercentnumberAnnual advisory fee, percent
aumstringAssets under advice in the scheme, decimal string with 2 places
inceptionDatestringYYYY-MM-DD
constituentCountintegerNumber of stocks currently in the basket
returnsobjectTrailing returns, percent, as decimal strings with 4 places. Keys: 1m, 3m, 6m, 1y, 2y, 3y, 5y, sinceInception. Any key can be null when the scheme is younger than that period.
navSeriesarray~12 monthly NAV points, oldest first, rebased to 100 — enough for a card sparkline. Empty array for a scheme with less than a month of history.
Every return can be null, including the headline one. A scheme launched eight months ago has no 1y figure, and rendering null as 0% would misstate performance. Show a dash and pick the longest period that is present.
Returns are past performance and must be labelled as such. Whatever your card design, the period and the as-of date have to be visible next to any percentage — returnsAsOf is provided for exactly this.

Scope

RuleDetail
Your advisors onlyThe list is limited to advisors mapped to your brokerage on Artham. Adding an advisor is a configuration change on our side — tell us and it appears on the next call.
Live schemes onlySchemes that are closed to new subscription are omitted. A scheme disappearing from the list means stop showing its card.
RefreshReturns update once daily after the overnight NAV run. Caching for a few hours is fine; caching for days will show stale performance.

5. API 2 — Webview Link Required

Call this the moment the user taps a card or your Artham entry point, and open the returned URL in a webview. The URL is pre-signed and specific to one client — it carries the session, so the user is never asked to sign in to Artham.

POST /api/v1/partner/webview/link Pre-signed, client-specific webview URL

Endpoint & Method

ItemValue
MethodPOST
Path/api/v1/partner/webview/link
AuthenticationX-Api-Key + X-Signature — see Section 2
Called fromYour backend, not the app — see the warning in Section 2

Request Body

{
  "clientCode": "PL889900",
  "schemeCode": "ARTHAM-EQ-001"
}

Request Fields

KeyRequiredDescription
clientCodeYesYour client / UCC code — the identifier this client is known by in your systems. The returned link is bound to it.
schemeCodeNoPresent → the link opens that scheme's page (a card was tapped). Absent → the link opens the discovery page (your Artham header was tapped). Must be a schemeCode from API 1.
Two keys, and no client identity in the payload. The request carries no name, PAN, mobile or email — Artham resolves the client from clientCode against the details it already holds for your brokerage. A code Artham does not recognise is rejected rather than created, so a client must exist on our side before their first webview link.

Response — 200 OK

{
  "success": true,
  "error": null,
  "data": {
    "url": "https://invest.artham.co/discover/quality-compounders?t=eyJhbGciOi...",
    "target": "SCHEME",
    "expiresAt": "2026-09-01T10:35:00+05:30",
    "ttlSeconds": 300
  }
}

Response Fields

FieldTypeDescription
urlstringOpen this in a webview, unmodified. Treat it as opaque.
targetstring"SCHEME" or "DISCOVERY" — echoes which page the link resolves to
expiresAtstringISO 8601 with IST offset
ttlSecondsintegerSeconds until expiry (300 = 5 minutes)
Request the link at the moment of the tap, and open it immediately. The token in the URL is short-lived and single-use: it is consumed when the webview loads. Pre-fetching links to have them ready, or reusing one across two launches, produces an expired-link screen.
Never log, forward or display the URL. It authenticates as that client — anyone holding it within the TTL is that client. It should travel from your backend to the webview and nowhere else.
Do not modify the URL. Appending, reordering or re-encoding query parameters invalidates the signature. Pass it through byte for byte.

Error Responses

HTTPerror.codeWhen
400INVALID_REQUESTclientCode missing or empty
404CLIENT_NOT_FOUNDNo client with that clientCode is mapped to your brokerage on Artham
404SCHEME_NOT_FOUNDschemeCode does not exist
422SCHEME_NOT_AVAILABLEThe scheme exists but is not distributable by your brokerage

6. Inside the Webview

Once the URL is open, the journey is Artham's: scheme detail, risk profiling, KYC, advisory consent, mandate setup and order placement. Your app does not need to implement, mirror or track any of these steps. What it does need is a webview configured to let them work.

Webview Requirements

RequirementWhy
JavaScript enabledThe application will not render without it
DOM storage and cookies enabledHolds the session across the journey's steps
Third-party redirects allowedeSign and payment steps hand off to external providers and return. A webview restricted to artham.co breaks mandate setup.
Downloads permittedThe user can save agreements and reports as PDFs

Exiting

Artham signals completion or a user-initiated exit by posting a message to the webview host:

{ "source": "artham", "event": "EXIT", "reason": "COMPLETED" | "USER_CLOSED" }

Close the webview when you receive it. reason is informational — both cases mean the same thing for your app. Also give the user your own way out, such as a close button in your chrome, so a network failure inside the webview cannot trap them.

No state flows back to your app on exit. Whether the user invested is not carried in the exit event — it reports only that the webview is finished. Investment outcomes reach you through your existing post-trade reporting with Artham, not through this integration.

7. Sandbox & Testing

Integration Steps

  1. Artham shares credentials — an API Key and Shared Secret for Sandbox, sent over a secure channel.
  2. You wire up the two calls — scheme list and webview link, both signed, both from your backend.
  3. You build the cards — using the API 1 fields, in your own design.
  4. End-to-end test — you launch the webview for a test client against Sandbox, and we walk one full journey together, from card tap through to a placed order.
  5. Go live — we issue production credentials. No code change beyond the base URL and the credentials.

Test Checklist

Authentication

Test CaseExpected Result
Self-test both digests against the demo secret in Section 2Both match exactly — do this before your first call
Valid key + correct signature200
Valid key + tampered signature401 with AUTH_TOKEN_INVALID
Unknown API key401 with AUTH_TOKEN_INVALID
Headers omitted401 with AUTH_REQUIRED
Sign the full URL instead of the path401 — sign /api/v1/partner/schemes only
On API 2, re-serialise the body after signing it401 — confirms you must send the exact bytes you signed

API 1 — Scheme List

Test CaseExpected Result
Fetch the list200; count matches the array length
Render a scheme with "5y": nullCard shows a dash, never 0%
Render a scheme with logoUrl: nullFalls back to initials, no broken image
Render a scheme with an empty navSeriesCard renders without a sparkline, no layout break

API 2 — Webview Link

Test CaseExpected Result
Request with a schemeCodetarget: "SCHEME"; webview opens that scheme's page
Request without a schemeCodetarget: "DISCOVERY"; webview opens the discovery page
Unknown clientCode404 with CLIENT_NOT_FOUND
Unknown schemeCode404 with SCHEME_NOT_FOUND
Open the same URL a second timeExpired-link screen — confirms the link is single-use
Open a URL more than 5 minutes after issueExpired-link screen
Open links for two different clients in turnEach webview shows only its own client's data

Webview

Test CaseExpected Result
Complete a mandate step that redirects to an external providerRedirect completes and returns into the webview
Kill the network mid-journeyYour own close control still exits the webview
Receive the EXIT messageYour app closes the webview

Support

For integration questions, contact the Artham engineering team: