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.
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.
VALIDATION_ERRORThe portfolio body is invalid. details lists the problem with each field.TICKERS_NOT_FOUNDThe portfolio includes an unknown tickerMISSING_PRICE_DATAA portfolio holding has no current priceNOT_AUTHENTICATEDNo X-API-Key header was sentAUTHENTICATION_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.PERMISSION_DENIEDYour plan doesn't include reports or exportsSECURITY_NOT_FOUNDNo screened stock matches the symbolREPORT_NOT_FOUNDNo report has this IDNOT_FOUNDThe page number or next_token is invalidAMBIGUOUS_IDENTIFIERThe symbol is listed on more than one exchange. Use EXCHANGE:TICKER or the exchange query; details.options lists the choices.THROTTLEDRate limit reached. Retry after the seconds in the Retry-After header.—Unexpected server error. The body may not be JSON.{
"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.
OpenAPI schema (YAML)
https://api.toyyib.app/api/v1/schema/
The raw OpenAPI 3 document.
OpenAPI schema (JSON)
https://api.toyyib.app/api/v1/schema/?format=json
The same document as JSON, for tools that prefer it.
Swagger UI
https://api.toyyib.app/api/v1/docs/
Browse the schema and send requests with your own key.
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
symbolpath string
Ticker, UUID, or exchange-qualified symbol, for example TESTCO or NGX:TESTCO.
exchangequery string
Optional exchange code such as NGX or NASD. Used to disambiguate bare tickers.
curl "https://api.toyyib.app/api/v1/stocks/TESTCO/compliance?exchange=NGX" \ -H "X-API-Key: sk_test_your_key_here"
{
"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"
}Stocks
List Compliant Stocks
Retrieve screened stocks whose status is COMPLIANT. This is a convenience endpoint over the main compliance list.
Parameters
exchangequery string
Optional exchange code. Omit to include all active markets.
sectorquery string
Filter by sector name, case-insensitive.
page_sizequery integer
Items per page. Defaults to 50; maximum is 200.
next_tokenquery string
Opaque cursor returned by the previous page.
curl "https://api.toyyib.app/api/v1/stocks/compliant?exchange=NGX&page_size=2" \ -H "X-API-Key: sk_test_your_key_here"
{
"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"
}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
exchangequery string
Filter by exchange code such as NGX or NASD. Omit for all.
statusquery string
Filter by COMPLIANT, NON_COMPLIANT, or QUESTIONABLE.
sectorquery string
Filter by sector name, case-insensitive.
page_sizequery integer
Items per page. Defaults to 50; maximum is 200.
next_tokenquery string
Opaque cursor returned by the previous page.
curl "https://api.toyyib.app/api/v1/stocks/compliance?exchange=NGX&page_size=50" \ -H "X-API-Key: sk_test_your_key_here"
{
"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"
}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
symbolpath string
Ticker, UUID, or exchange-qualified symbol, for example TESTCO or NGX:TESTCO.
exchangequery string
Optional exchange code such as NGX or NASD. Used to disambiguate bare tickers.
curl "https://api.toyyib.app/api/v1/stocks/TESTPURE/report?exchange=NGX" \ -H "X-API-Key: sk_test_your_key_here"
{
"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"
}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
exchangequery string
Filter by exchange code such as NGX.
statusquery string
Filter by COMPLIANT, NON_COMPLIANT, or QUESTIONABLE.
page_sizequery integer
Planned items per page. Default 50; maximum 200.
next_tokenquery string
Planned opaque cursor returned by the previous page.
curl "https://api.toyyib.app/api/v1/etfs/compliance?exchange=NGX&page_size=50" \ -H "X-API-Key: sk_test_your_key_here"
{
"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"
}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 "https://api.toyyib.app/api/v1/exchanges" \ -H "X-API-Key: sk_test_your_key_here"
{
"success": true,
"data": {
"items": [
{
"code": "NASD",
"name": "NASD OTC Securities Exchange",
"type": "OTC"
},
{
"code": "NGX",
"name": "Nigerian Exchange",
"type": "EXCHANGE"
}
]
},
"message": "Exchanges retrieved successfully"
}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
holdingsarray
One to fifty holdings, with no duplicate tickers.
holdings[].tickerstring
Ticker symbol, case-insensitive.
holdings[].sharesnumber
Number of shares held. Minimum 1.
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}
]
}'{
"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"
}Reports
List Reports
Retrieve paginated compliance reports.
Parameters
typestring
Filter by monthly, quarterly, or special.
pageinteger
Page number.
curl "https://api.toyyib.app/api/v1/reports?type=quarterly&page=1" \ -H "X-API-Key: sk_live_your_pro_key"
{
"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"
}Reports
Report Statistics
Get report generation and download statistics, including upcoming report schedules.
Parameters
This endpoint takes no parameters.
curl "https://api.toyyib.app/api/v1/reports/stats" \ -H "X-API-Key: sk_live_your_pro_key"
{
"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"
}Reports
Download Report
Get a download URL for a specific compliance report.
Parameters
report_iduuid
The report unique identifier.
curl "https://api.toyyib.app/api/v1/reports/019432b2-.../download" \ -H "X-API-Key: sk_live_your_enterprise_key"
{
"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"
}Account
API Usage
Check current API key usage and rate-limit status.
Parameters
This endpoint takes no parameters.
curl "https://api.toyyib.app/api/v1/usage" \ -H "X-API-Key: sk_test_your_key_here"
{
"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.