OppsRadar API
Embed live scholarships, internships, fellowships, grants, competitions and hackathons into your own app, bot or website. One API key. Clean JSON. Ready in under 2 minutes.
🎉 Free tier available. Get your key instantly at oppsradar.com → For Developers — no credit card required.
Base URL
All endpoints are served over HTTPS. Requests over plain HTTP are not supported.
Authentication
Pass your API key as a Bearer token in the Authorization header
on every request to the /api/v1/* endpoints.
GET /api/v1/opportunities HTTP/1.1
Host: oppsradar.com
Authorization: Bearer ordk_your_api_key_here
⚠️ Keep your key secret. It grants full read access for your tier. Do not expose it in client-side JavaScript that ships to the browser — proxy through your own server instead.
Key format
Keys follow the format ordk_<40 hex chars>, e.g.:
ordk_3f8a12b9c74e21d05a6f8b3c19e4d2a70f5c6b8e
Getting a key
Visit oppsradar.com → For Developers, fill in your name and email, and your free key will be shown on screen immediately and only once. Store it somewhere safe — it cannot be retrieved again.
Quick start
Step 1 — Get your free API key
Go to oppsradar.com → For Developers and fill in the form. Your key appears instantly.
Step 2 — Make your first request
curl https://oppsradar.com/api/v1/opportunities \
-H "Authorization: Bearer ordk_your_key_here"
Step 3 — Filter the results
curl "https://oppsradar.com/api/v1/opportunities?type=Scholarship&country=Nigeria&limit=20" \
-H "Authorization: Bearer ordk_your_key_here"
Step 4 — Parse and build
// Browser / ES module example
const res = await fetch(
'https://oppsradar.com/api/v1/opportunities?type=Scholarship&limit=10',
{ headers: { Authorization: 'Bearer ordk_your_key_here' } }
)
const { opportunities, meta } = await res.json()
console.log(`Loaded ${opportunities.length} results`)
console.log(`Used ${meta.daily_requests_used} of ${meta.daily_limit} requests today`)
Endpoints
Returns a filtered list of published, non-expired opportunities. Sorted by deadline ascending (no-deadline entries appear last).
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type |
string | No | Filter by opportunity type. One of: Scholarship, Internship, Fellowship, Grant, Competition, Hackathon |
level |
string | No | Partial match on education level. e.g. Masters, PhD, Undergraduate |
country |
string | No | Partial match on countries field. e.g. Nigeria, Africa, International |
field |
string | No | Partial match on field/subject area. e.g. Engineering, Law |
page |
integer | No | Batch page number for pagination. Default: 1. Increments to fetch new opportunities. Automatically wraps back to 1 once the full list is viewed. |
limit |
integer | No | Max results to return per batch. Default: 5 (Free) / 20 (Paid). Max: 5 (Free), 100 (Paid). |
Example — scholarships open to Nigerian students
GET /api/v1/opportunities?type=Scholarship&country=Nigeria&limit=20
Authorization: Bearer ordk_your_key_here
Example — engineering internships
GET /api/v1/opportunities?type=Internship&field=Engineering
Authorization: Bearer ordk_your_key_here
Register for a free API key. The key is returned in the response body once only — store it immediately.
Request body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Your full name (max 120 chars) |
email | string | Yes | Your email address — one key per email |
use | string | No | Brief description of what you are building (max 500 chars) |
Example request
curl -X POST https://oppsradar.com/api/developer/signup \
-H "Content-Type: application/json" \
-d '{
"name": "Adaeze Okonkwo",
"email": "adaeze@example.com",
"use": "Building a Telegram bot for my university community"
}'
Success response
{
"ok": true,
"message": "Your free API key has been created. Save it now — it is shown only once.",
"api_key": "ordk_3f8a12b9c74e21d05a6f8b3c19e4d2a70f5c6b8e",
"key_prefix": "ordk_3f8a12b",
"tier": "free",
"daily_limit": 20,
"docs": "https://oppsradar.com/docs"
}
Public feed — no key needed. Returns up to 50 published opportunities with no filtering. Use this for a simple embed widget.
curl https://oppsradar.com/api/opportunities
Response shape
Opportunity object
| Field | Type | Description |
|---|---|---|
id | integer | Unique opportunity ID |
title | string | Name of the opportunity |
organization | string | Organisation offering it |
type | string | One of: Scholarship · Internship · Fellowship · Grant · Competition · Hackathon |
description | string | Summary of the opportunity |
eligibility | string | Who can apply |
countries | string | Eligible countries (comma-separated or "International") |
fields | string | Subject areas / disciplines |
level | string | Education level(s) |
deadline | string | null | ISO date YYYY-MM-DD or null if rolling |
funding | string | Funding description (e.g. "Fully funded", "Stipend") |
application_url | string | Official application link |
verified | integer | 1 = verified by OppsRadar team, 0 = unverified |
Meta object (only in /api/v1/ responses)
| Field | Type | Description |
|---|---|---|
count | integer | Number of results returned |
tier | string | Your plan: free, starter, or builder |
daily_requests_used | integer | Requests you have made today (UTC) |
daily_limit | integer | "unlimited" | Your daily cap |
Full response example
{
"opportunities": [
{
"id": 1,
"title": "Erasmus Mundus Joint Masters",
"organization": "European Commission",
"type": "Scholarship",
"description": "Prestigious EU-funded scholarship for international Masters study.",
"eligibility": "Graduates from non-EU countries",
"countries": "International",
"fields": "All fields",
"level": "Masters",
"deadline": "2025-02-15",
"funding": "Fully funded",
"application_url": "https://erasmus-plus.ec.europa.eu",
"verified": 1
}
],
"meta": {
"count": 1,
"tier": "free",
"daily_requests_used": 3,
"daily_limit": 20
}
}
Error codes
Success. Results (may be an empty array if no matches).
Missing or invalid API key. Check the Authorization: Bearer header.
Daily rate limit reached for your plan. Resets at midnight UTC. Upgrade for a higher limit.
Bad request — usually a malformed JSON body on POST endpoints.
Server error. Rare. If persistent, email hello@oppsradar.com.
Error response shape
{
"error": "Daily limit of 20 requests reached for your free plan. Upgrade at oppsradar.com/developers",
"limit": 20,
"used": 21,
"tier": "free"
}
Rate limits
Limits are per API key, per UTC calendar day. The counter resets at 00:00 UTC.
| Plan | Requests / day | Price |
|---|---|---|
| Free | 5 (max 5 items / call) | $0 — forever |
| Starter | 1,000 (max 100 items / call) | $19 / month |
| Builder | Unlimited | $49 / month |
The current usage is returned in every response inside the meta object so you can track it programmatically.
Pricing & plans
- 10 requests / day
- Up to 10 opportunities / request
- All filters
- JSON response
- 1,000 requests / day
- Up to 100 opportunities / request
- All filters + Job vs Internship separation
- Email support
- Unlimited requests (no throttling)
- Full schema & automated webhooks
- Commercial redistribution rights
- Priority 1-on-1 support
How to upgrade
Paid plans are processed via Paystack. Visit the upgrade section on the Developers page, pick your plan, and complete the Paystack checkout. Your key is upgraded within seconds — no new key needed.
💳 We accept all major cards (Visa, Mastercard) and bank transfers via Paystack. Nigerian cards and international cards are both supported.
Examples
JavaScript — Fetch API
const API_KEY = 'ordk_your_key_here'
async function getScholarships(country = 'Nigeria') {
const params = new URLSearchParams({
type: 'Scholarship',
country,
limit: '20',
})
const res = await fetch(
`https://oppsradar.com/api/v1/opportunities?${params}`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
)
if (!res.ok) {
const err = await res.json()
throw new Error(err.error)
}
return res.json()
}
// Usage
const { opportunities, meta } = await getScholarships()
console.log(opportunities) // array of opportunity objects
console.log(meta) // { count, tier, daily_requests_used, daily_limit }
Node.js — Axios
const axios = require('axios')
const client = axios.create({
baseURL: 'https://oppsradar.com',
headers: { Authorization: `Bearer ${process.env.OPPSRADAR_API_KEY}` },
})
async function getOpportunities(filters = {}) {
const { data } = await client.get('/api/v1/opportunities', { params: filters })
return data
}
// Get all hackathons, max 30
const { opportunities } = await getOpportunities({ type: 'Hackathon', limit: 30 })
Python — requests
import requests, os
API_KEY = os.environ["OPPSRADAR_API_KEY"]
BASE = "https://oppsradar.com"
def get_opportunities(**filters):
r = requests.get(
f"{BASE}/api/v1/opportunities",
headers={"Authorization": f"Bearer {API_KEY}"},
params=filters,
timeout=10,
)
r.raise_for_status()
return r.json()
# PhD fellowships open to African applicants
data = get_opportunities(type="Fellowship", level="PhD", country="Africa")
for opp in data["opportunities"]:
print(opp["title"], "—", opp["deadline"])
Telegram bot idea (Node.js + node-telegram-bot-api)
const TelegramBot = require('node-telegram-bot-api')
const bot = new TelegramBot(process.env.BOT_TOKEN, { polling: true })
bot.onText(/\/scholarships/, async (msg) => {
const chatId = msg.chat.id
const res = await fetch(
'https://oppsradar.com/api/v1/opportunities?type=Scholarship&country=Nigeria&limit=5',
{ headers: { Authorization: `Bearer ${process.env.OPPSRADAR_API_KEY}` } }
)
const { opportunities } = await res.json()
const text = opportunities
.map(o => `📌 *${o.title}*\n🏛 ${o.organization}\n⏰ Deadline: ${o.deadline ?? 'Rolling'}\n🔗 ${o.application_url}`)
.join('\n\n')
bot.sendMessage(chatId, text || 'No scholarships found right now.', { parse_mode: 'Markdown' })
})
💡 Store OPPSRADAR_API_KEY as an environment variable — never hardcode it in your source code.