Toyyib Developer Platform

Add Shariah stock screening to your product.

Query compliance data for NGX-listed stocks, analyze user portfolios, monitor API usage, and access advanced Shariah reports through a server-side API-key integration.

API base URL

Sandbox and production keys

Base URL
https://api.toyyib.app/api/v1

X-API-Key: sk_test_your_key_here

10

live APIs

API

keys

1

coming soon

Stocks

List screened NGX-listed stocks.

Portfolio scoring

Analyze holdings and purification amounts.

Reports

Retrieve compliance reports for equities.

Usage

Monitor daily quota and API key activity.

Getting started

Authenticate with X-API-Key

Every external API request requires an API key in the X-API-Key header. Sandbox keys use sk_test_ and production keys use sk_live_.

Key formats

sk_test_

Sandbox key for development and testing.

sk_live_

Production key for live data access.

Never expose API keys in browser code, public repositories, or client-side requests. Keep requests on your server.
cURL
curl "https://api.toyyib.app/api/v1/stocks/compliance?exchange=NGX&page_size=50" \
  -H "X-API-Key: sk_test_your_key_here"

Testing

Build against the sandbox

sk_test_ keys are served a fixed set of synthetic stocks that cover every response shape your integration has to handle. Every example on this page uses them, so you can run each one with your sandbox key.

NGX:TESTCOCOMPLIANTClean compliant stock; purification_ratio is 0.
NGX:TESTPURECOMPLIANTCompliant with impure income, so purification_ratio is above 0.
NGX:TESTDOUBTQUESTIONABLEDoubtful financial ratios.
NGX:TESTRATIONON_COMPLIANTFails the financial ratio screen.
NGX:TESTBIZNON_COMPLIANTFails the business screen; financial_screen is NOT_APPLICABLE.
TESTAMBIGCOMPLIANTListed on NGX and NASD; a bare symbol returns 409 AMBIGUOUS_IDENTIFIER.
NGX:TESTPENDUnscreenedLeft out of lists; a lookup returns 404.
NGX:TESTNOPRICECOMPLIANTNo price, so /portfolio/analyze returns 400 MISSING_PRICE_DATA.

Separate data

Sandbox keys never see real stocks, and live keys never see fixtures. A real ticker such as DANGCEM returns 404 SECURITY_NOT_FOUND on a sandbox key.

Every endpoint

Sandbox keys can call Pro and Enterprise endpoints regardless of plan, with a flat 1,000 requests a day and 60 a minute.

X-API-Mode: sandbox

Sent on every sandbox response, so you can assert which environment answered.

Sample report

The reports endpoints return one sample monthly report. It has no file attached, so download_url is null.

Traffic controls

Rate limits are enforced per API key

Each key has a daily quota, which resets at 00:00 UTC, and a per-minute limit. Responses include rate-limit headers so your application can track remaining quota and back off gracefully. GET /usage returns the same figures.

X-RateLimit-Limit-Daily

Requests allowed per day for this key

X-RateLimit-Remaining-Daily

Requests left today

X-RateLimit-Limit-Minute

Requests allowed per minute for this key

Retry-After

Seconds to wait before retrying, sent with 429 responses

Error handling

Predictable JSON errors

The API uses standard HTTP status codes and wraps validation, authentication, authorization, and rate-limit errors in a consistent shape. A path that doesn't exist, or an unexpected server error, may not return JSON.

400VALIDATION_ERRORThe portfolio body is invalid. details lists the problem with each field.
400TICKERS_NOT_FOUNDThe portfolio includes an unknown ticker
400MISSING_PRICE_DATAA portfolio holding has no current price
401NOT_AUTHENTICATEDNo X-API-Key header was sent
401AUTHENTICATION_FAILEDThe key is invalid, deactivated or expired, its business or plan is inactive, or it is a live key without production access. The message says which.
403PERMISSION_DENIEDYour plan doesn't include reports or exports
404SECURITY_NOT_FOUNDNo screened stock matches the symbol
404REPORT_NOT_FOUNDNo report has this ID
404NOT_FOUNDThe page number or next_token is invalid
409AMBIGUOUS_IDENTIFIERThe symbol is listed on more than one exchange. Use EXCHANGE:TICKER or the exchange query; details.options lists the choices.
429THROTTLEDRate limit reached. Retry after the seconds in the Retry-After header.
500—Unexpected server error. The body may not be JSON.
Error format
{
  "success": false,
  "error": {
    "code": "AUTHENTICATION_FAILED",
    "message": "Invalid API key."
  }
}

Tooling

OpenAPI specification

The external API is described by an OpenAPI 3 schema. Import it into Postman or Insomnia, or generate a typed client with your usual codegen tool.

GET/api/v1/stocks/{symbol}/complianceLive

Stocks

Single Stock Compliance

Retrieve the headline Shariah compliance status for one screened stock. Use the exchange query or an EXCHANGE:TICKER symbol when a ticker exists on more than one market.

Parameters

symbol

path string

Ticker, UUID, or exchange-qualified symbol, for example TESTCO or NGX:TESTCO.

exchange

query string

Optional exchange code such as NGX or NASD. Used to disambiguate bare tickers.

curl
curl "https://api.toyyib.app/api/v1/stocks/TESTCO/compliance?exchange=NGX" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "symbol": "TESTCO",
    "name": "Sandbox Compliant Foods Plc",
    "exchange": "NGX",
    "status": "COMPLIANT",
    "report_date": "2026-06-30T00:00:00Z"
  },
  "message": "Security compliance retrieved successfully"
}
GET/api/v1/stocks/compliantLive

Stocks

List Compliant Stocks

Retrieve screened stocks whose status is COMPLIANT. This is a convenience endpoint over the main compliance list.

Parameters

exchange

query string

Optional exchange code. Omit to include all active markets.

sector

query string

Filter by sector name, case-insensitive.

page_size

query integer

Items per page. Defaults to 50; maximum is 200.

next_token

query string

Opaque cursor returned by the previous page.

curl
curl "https://api.toyyib.app/api/v1/stocks/compliant?exchange=NGX&page_size=2" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "items": [
      {
        "symbol": "TESTCO",
        "name": "Sandbox Compliant Foods Plc",
        "exchange": "NGX",
        "status": "COMPLIANT",
        "report_date": "2026-06-30T00:00:00Z",
        "purification_ratio": 0.0
      },
      {
        "symbol": "TESTPURE",
        "name": "Sandbox Purification Industries Plc",
        "exchange": "NGX",
        "status": "COMPLIANT",
        "report_date": "2026-06-30T00:00:00Z",
        "purification_ratio": 4.0
      }
    ],
    "next_token": "cD0wMTlmNDJhYi05NDY4LTczZTgt..."
  },
  "message": "Securities retrieved successfully"
}
GET/api/v1/stocks/complianceLive

Stocks

List Stocks Compliance

Retrieve paginated basic compliance reports for all screened stocks on one exchange, or on every active exchange. Unscreened stocks are left out. purification_ratio is null for NON_COMPLIANT stocks, which are avoided rather than purified.

Parameters

exchange

query string

Filter by exchange code such as NGX or NASD. Omit for all.

status

query string

Filter by COMPLIANT, NON_COMPLIANT, or QUESTIONABLE.

sector

query string

Filter by sector name, case-insensitive.

page_size

query integer

Items per page. Defaults to 50; maximum is 200.

next_token

query string

Opaque cursor returned by the previous page.

curl
curl "https://api.toyyib.app/api/v1/stocks/compliance?exchange=NGX&page_size=50" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "items": [
      {
        "symbol": "TESTCO",
        "name": "Sandbox Compliant Foods Plc",
        "exchange": "NGX",
        "status": "COMPLIANT",
        "report_date": "2026-06-30T00:00:00Z",
        "purification_ratio": 0.0
      },
      {
        "symbol": "TESTDOUBT",
        "name": "Sandbox Doubtful Holdings Plc",
        "exchange": "NGX",
        "status": "QUESTIONABLE",
        "report_date": "2026-06-30T00:00:00Z",
        "purification_ratio": 4.0
      },
      {
        "symbol": "TESTBIZ",
        "name": "Sandbox Breweries Plc",
        "exchange": "NGX",
        "status": "NON_COMPLIANT",
        "report_date": "2026-06-30T00:00:00Z",
        "purification_ratio": null
      }
    ],
    "next_token": null
  },
  "message": "Securities retrieved successfully"
}
GET/api/v1/stocks/{symbol}/reportLivePro and Enterprise

Stocks

Full Shariah Compliance Report

Retrieve the advanced compliance report for one screened stock, including business and financial screens, revenue breakdown, and AAOIFI screening ratios. When the business screen fails, financial_screen is NOT_APPLICABLE (try TESTBIZ in the sandbox). The ratio fields are fractions and are null when no ratio screening is on file.

Parameters

symbol

path string

Ticker, UUID, or exchange-qualified symbol, for example TESTCO or NGX:TESTCO.

exchange

query string

Optional exchange code such as NGX or NASD. Used to disambiguate bare tickers.

curl
curl "https://api.toyyib.app/api/v1/stocks/TESTPURE/report?exchange=NGX" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "symbol": "TESTPURE",
    "raw_symbol": "TESTPURE",
    "name": "Sandbox Purification Industries Plc",
    "exchange": "NGX",
    "sector": "Industrial Goods",
    "currency": "NGN",
    "status": "COMPLIANT",
    "business_screen": "COMPLIANT",
    "financial_screen": "COMPLIANT",
    "screening_standard": "AAOIFI",
    "report_date": "2026-06-30T00:00:00Z",
    "compliant_revenue": 96.0,
    "non_compliant_revenue": 0.0,
    "questionable_revenue": 4.0,
    "securities_to_market_cap_ratio": null,
    "debt_to_market_cap_ratio": null
  },
  "message": "Compliance report retrieved successfully"
}
GET/api/v1/etfs/complianceComing soon

ETFs

List ETF Compliance Reports

ETF-level Shariah compliance derived from each fund's underlying holdings. This endpoint is not live yet; the shape below is a preview and may change before launch.

Parameters

exchange

query string

Filter by exchange code such as NGX.

status

query string

Filter by COMPLIANT, NON_COMPLIANT, or QUESTIONABLE.

page_size

query integer

Planned items per page. Default 50; maximum 200.

next_token

query string

Planned opaque cursor returned by the previous page.

curl
curl "https://api.toyyib.app/api/v1/etfs/compliance?exchange=NGX&page_size=50" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "items": [
      {
        "symbol": "LOTUSHAL15",
        "name": "Lotus Halal Equity ETF",
        "exchange": "NGX",
        "status": "COMPLIANT",
        "compliant_holdings": 100,
        "non_compliant_holdings": 0,
        "questionable_holdings": 0,
        "report_date": "2026-05-31T00:00:00Z"
      }
    ],
    "next_token": null
  },
  "message": "ETF compliance reports retrieved successfully"
}
GET/api/v1/exchangesLive

Markets

List Exchanges

Retrieve the exchanges and OTC markets the API recognises. Use the code as the exchange filter on the stock endpoints. Screened coverage is NGX-listed stocks today; NASD is planned.

Parameters

This endpoint takes no parameters.

curl
curl "https://api.toyyib.app/api/v1/exchanges" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "items": [
      {
        "code": "NASD",
        "name": "NASD OTC Securities Exchange",
        "type": "OTC"
      },
      {
        "code": "NGX",
        "name": "Nigerian Exchange",
        "type": "EXCHANGE"
      }
    ]
  },
  "message": "Exchanges retrieved successfully"
}
POST/api/v1/portfolio/analyzeLive

Portfolio

Analyze Portfolio

Submit holdings and receive portfolio-level compliance scoring, value breakdowns, and purification amounts. Unknown tickers return 400 TICKERS_NOT_FOUND, and holdings without a current price return 400 MISSING_PRICE_DATA.

Parameters

holdings

array

One to fifty holdings, with no duplicate tickers.

holdings[].ticker

string

Ticker symbol, case-insensitive.

holdings[].shares

number

Number of shares held. Minimum 1.

curl
curl -X POST "https://api.toyyib.app/api/v1/portfolio/analyze" \
  -H "X-API-Key: sk_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "holdings": [
      {"ticker": "TESTCO", "shares": 500},
      {"ticker": "TESTPURE", "shares": 200}
    ]
  }'
Response
{
  "success": true,
  "data": {
    "summary": {
      "total_value": 15150.0,
      "compliance_score": 93,
      "compliance_status": "compliant",
      "compliant_value": 15150.0,
      "compliant_percentage": 100.0,
      "non_compliant_value": 0.0,
      "non_compliant_percentage": 0.0,
      "doubtful_value": 0.0,
      "doubtful_percentage": 0.0,
      "total_purification_amount": 96.0,
      "holdings_count": 2,
      "analyzed_at": "2026-10-11T12:47:00.509798+00:00"
    },
    "holdings": [
      {
        "ticker": "TESTCO",
        "company_name": "Sandbox Compliant Foods Plc",
        "shares": 500,
        "price": 25.5,
        "value": 12750.0,
        "weight": 84.2,
        "compliance_status": "compliant",
        "compliance_score": 95,
        "purification_per_share": 0.0,
        "purification_amount": 0.0
      },
      {
        "ticker": "TESTPURE",
        "company_name": "Sandbox Purification Industries Plc",
        "shares": 200,
        "price": 12.0,
        "value": 2400.0,
        "weight": 15.8,
        "compliance_status": "compliant",
        "compliance_score": 85,
        "purification_per_share": 0.48,
        "purification_amount": 96.0
      }
    ]
  },
  "message": "Portfolio analysis completed successfully"
}
GET/api/v1/reportsLivePro and Enterprise

Reports

List Reports

Retrieve paginated compliance reports.

Parameters

type

string

Filter by monthly, quarterly, or special.

page

integer

Page number.

curl
curl "https://api.toyyib.app/api/v1/reports?type=quarterly&page=1" \
  -H "X-API-Key: sk_live_your_pro_key"
Response
{
  "success": true,
  "data": {
    "reports": [
      {
        "id": "019432b2-...",
        "title": "Q2 2026 Compliance Report",
        "description": "Quarterly Shariah screening of NGX stocks.",
        "type": "quarterly",
        "date": "2026-06-30",
        "file_size": 245760,
        "file_size_formatted": "240.0 KB",
        "download_url": "https://api.toyyib.app/media/reports/q2-2026.pdf",
        "created_at": "2026-07-05T09:00:00Z"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 20,
      "total_pages": 1,
      "total_items": 1,
      "has_next": false,
      "has_previous": false
    }
  },
  "message": "Reports retrieved successfully"
}
GET/api/v1/reports/statsLivePro and Enterprise

Reports

Report Statistics

Get report generation and download statistics, including upcoming report schedules.

Parameters

This endpoint takes no parameters.

curl
curl "https://api.toyyib.app/api/v1/reports/stats" \
  -H "X-API-Key: sk_live_your_pro_key"
Response
{
  "success": true,
  "data": {
    "total_reports_generated": 24,
    "total_downloads": 156,
    "report_schedule": [
      {
        "type": "monthly",
        "description": "Generated on the 15th of each month",
        "next_report_date": "2026-11-15T12:47:00.531050+00:00"
      },
      {
        "type": "quarterly",
        "description": "Available 5 days after quarter end",
        "next_report_date": "2026-12-16T12:47:00.531050+00:00"
      }
    ]
  },
  "message": "Report statistics retrieved successfully"
}
GET/api/v1/reports/{report_id}/downloadLiveEnterprise

Reports

Download Report

Get a download URL for a specific compliance report.

Parameters

report_id

uuid

The report unique identifier.

curl
curl "https://api.toyyib.app/api/v1/reports/019432b2-.../download" \
  -H "X-API-Key: sk_live_your_enterprise_key"
Response
{
  "success": true,
  "data": {
    "download_url": "https://api.toyyib.app/media/reports/q1-2026.pdf",
    "file_name": "Q1 2026 Compliance Report.pdf",
    "file_size": 245760
  },
  "message": "Download URL generated successfully"
}
GET/api/v1/usageLive

Account

API Usage

Check current API key usage and rate-limit status.

Parameters

This endpoint takes no parameters.

curl
curl "https://api.toyyib.app/api/v1/usage" \
  -H "X-API-Key: sk_test_your_key_here"
Response
{
  "success": true,
  "data": {
    "key": {
      "prefix": "sk_test_",
      "name": "My Dev Key",
      "mode": "sandbox",
      "is_active": true,
      "last_used_at": "2026-10-11T12:46:58.957497+00:00"
    },
    "plan": {
      "name": "Free",
      "tier": "free",
      "allows_reports_access": false,
      "allows_export": false
    },
    "usage": {
      "daily_limit": 1000,
      "daily_used": 12,
      "daily_remaining": 988,
      "per_minute_limit": 60
    }
  },
  "message": "Usage data retrieved successfully"
}

Ready to add Shariah compliance to your platform?

Talk to the Halcore team about API keys, sandbox access, and business onboarding.