Developer Docs
Prodigio gives you two ways to integrate: the JavaScript SDK (recommended) handles auth, serialization, and types automatically, or call the REST API directly from any language. Both require an API key from your dashboard.
Base URL
https://hire.prodigio.ioCORS
All public endpoints return Access-Control-Allow-Origin: *. No proxy needed.
Quickstart
The official JavaScript SDK handles authentication, serialization, and typed responses automatically. It works in any browser or Node.js environment.
Install
npm install @prodigio-io/sdk
How the SDK works
The npm package is a thin typed loader. When Prodigio.init() is called, it automatically loads the badge runtime from cdn.prodigio.io/sdk/v2/sdk.js. This means badge fixes and improvements ship automatically — no npm update or redeploy needed on your end. Jobs and applications API calls are handled directly by the npm package.
Initialise the badge
Call Prodigio.init() once at your app root. The SDK automatically shows the badge only on your registered careers page and removes it on all other pages — no cleanup or framework-specific code needed. It watches client-side navigation internally and works with any router.
import { Prodigio } from '@prodigio-io/sdk';
// Call once at app root — badge is managed automatically
await Prodigio.init({ key: 'pk_live_your_key_here' });
// Paid tenants — paste the full snippet from your dashboard
await Prodigio.init({
key: 'pk_live_your_key_here',
badgeToken: 'your_signed_badge_token', // from Settings → Install snippet
});
Badge placement
The recommended way to control where the badge appears is to add an anchor element anywhere in your HTML. The SDK finds it automatically — no selectors or config needed.
<!-- Place this wherever you want the badge to appear — e.g. bottom of your careers page -->
<div data-prodigio-badge-anchor></div>
If you prefer to specify a container via JavaScript, use the badgeContainer option:
await Prodigio.init({
key: 'pk_live_your_key_here',
badgeContainer: '#careers-footer', // CSS selector for your container
});
If neither is provided, the SDK falls back to the first available semantic container: main → [role="main"] → #root → #__next → #app → body.
Required: meta tag in page head
The badge is injected by JavaScript, but compliance detection uses a server-side fetch that cannot execute JS. You must add this tag to your static HTML — without it your compliance status will always show as non-compliant.
<!-- index.html or your page <head> — must be server-rendered -->
<meta name="prodigio-badge" content="true" />
<!-- Next.js App Router: -->
export const metadata = { other: { 'prodigio-badge': 'true' } };
Fetch jobs and submit applications
import { Prodigio } from '@prodigio-io/sdk';
const prodigio = new Prodigio('pk_live_your_key_here');
// List active jobs
const jobs = await prodigio.jobs.list();
// Get a single job
const job = await prodigio.jobs.get('abc123');
// Upload a CV then submit an application
const cv = await prodigio.upload.cv(fileInput.files[0]);
const result = await prodigio.applications.submit({
jobId: 'abc123',
applicant: {
fullName: 'Jane Smith',
email: 'jane@example.com',
phone: '+233 20 000 0000',
},
cv,
coverLetter: 'I am excited to apply...',
});
console.log(result.id); // application ID
TypeScript
The SDK ships with full TypeScript types. No @types package needed.
SDK Reference
new Prodigio(apiKey)Creates a new client. Pass your API key as a string, or a config object.
// Simple
const prodigio = new Prodigio('pk_live_...');
// With config
const prodigio = new Prodigio({
apiKey: 'pk_live_...',
baseUrl: 'https://hire.prodigio.io', // optional
});
Methods
Prodigio.init(config)Promise<void>
Initialises the SDK. Call once at app root. Badge is shown only on the registered careers page and removed on all other pages automatically — no cleanup needed.
prodigio.jobs.list(params?)Promise<Job[]>
Returns active jobs. Optional: { status, department }
prodigio.jobs.get(jobId)Promise<Job>
Returns full job detail including HTML description.
prodigio.upload.cv(file, fileName?)Promise<UploadResult>
Uploads a CV. Accepts File or Blob. Returns the URL to pass to submit.
prodigio.upload.achievement(file)Promise<UploadResult>
Uploads an achievement image or video.
prodigio.applications.submit(params)Promise<ApplicationResult>
Submits a candidate application. AI scoring runs automatically.
prodigio.interest.submit(params)Promise<InterestResult>
Submits an expression of interest. No job listing required. Appears in the dashboard Interests section.
Prodigio.badge(poweredBy?)BadgeProps
Returns props to spread on an <a> element for manual badge rendering. poweredBy is optional — defaults to built-in attribution.
Prodigio.meta(){ name, content }
Returns props for a <meta> tag to add to your page <head> for server-side compliance detection. Required alongside init().
Prodigio.destroy()void
Removes the badge and resets the SDK. Use if you need to unmount manually.
Error handling
Failed requests throw a ProdigioError with message and status.
import { Prodigio, ProdigioError } from '@prodigio-io/sdk';
try {
const job = await prodigio.jobs.get('nonexistent');
} catch (err) {
if (err instanceof ProdigioError) {
console.log(err.status); // 404
console.log(err.message); // 'Job not found'
}
}
Authentication
Authenticate with your API key. Generate one from your Prodigio dashboard under Settings → API Keys. Two key types are available:
pk_live_Production key. Requests must originate from your registered careers page domain. Use this in production.
pk_test_Development key. localhost, 127.0.0.1, and [::1] are allowed by default on any port. Add preview and staging domains in your dashboard. Writes are sandboxed — they are saved with testMode: true and do not trigger emails, notifications, or AI pipelines.
Pass the key as a query parameter on GET requests, or as the x-api-key header on POST requests.
GET requests
/api/jobs?key=pk_live_...POST requests (header)
x-api-key: pk_live_...Deprecation notice
The ?slug= parameter is deprecated and will be removed on 1 Jan 2027. Migrate to ?key= as soon as possible. Both are accepted today. Responses using ?slug= include a Deprecation: true header.
Attribution
Free usage requires a visible attribution badge on your registered careers page. Prodigio.init() handles this automatically — the badge appears only on your careers page and is removed on all other pages. No cleanup or router integration needed.
<!-- Step 1: add to your static <head> (required for compliance detection) -->
<meta name="prodigio-badge" content="true" />
<!-- Step 2: place the anchor where you want the badge to appear -->
<div data-prodigio-badge-anchor></div>
// Step 3: call init() once at your app root
await Prodigio.init({ key: 'pk_live_your_key_here' });
Manual badge rendering
If you prefer to render the badge yourself in your own component:
import { Prodigio } from '@prodigio-io/sdk';
const { href, text, ...attrs } = Prodigio.badge();
// React: <a href={href} {...attrs}>{text}</a>
// HTML: el.href = href; el.textContent = text;
List jobs
Returns all active job postings for your company. Results are sorted newest first.
/api/jobs?key={your-api-key}publicAlso available at /api/v1/jobs — both endpoints are identical.
Query parameters
keystring required
Your API key. Required.
statusstring, optional
Filter by status. Defaults to active. Pass all to return every status.
departmentstring, optional
Filter by department name. Case-insensitive.
Response: array of job objects
[
{
"id": "abc123",
"title": "Frontend Engineer",
"companyName": "Summer Health",
"department": "Engineering",
"location": "Accra, Ghana",
"type": "full-time",
"status": "active",
"description": "<p>...</p>",
"requirements": "<ul>...</ul>",
"eligibilityCriteria": "<p>...</p>",
"salaryRange": {
"min": 3000,
"max": 5000,
"currency": "GHS",
"period": "monthly"
},
"applicationDeadline": "2026-06-30T23:59:59.000Z",
"createdAt": "2026-04-01T09:00:00.000Z",
"updatedAt": "2026-04-01T09:00:00.000Z",
"poweredBy": {
"text": "Hiring powered by Prodigio",
"url": "https://prodigio.io"
}
}
]
Status codes
200Returns array of listing objects, sorted newest first.401Missing or invalid API key.403API key not authorised for this domain. Use pk_test_ for local development.Get a job
Returns the full details for a single job, including description and requirements HTML.
/api/jobs/{jobId}?key={your-api-key}publicPath parameters
jobIdstring, required
The job ID returned from the list endpoint.
Response: job object
{
"id": "abc123",
"title": "Frontend Engineer",
"companyName": "Summer Health",
"department": "Engineering",
"location": "Accra, Ghana",
"type": "full-time",
"status": "active",
"description": "<p>...</p>",
"requirements": "<ul>...</ul>",
"eligibilityCriteria": "<p>...</p>",
"salaryRange": {
"min": 3000,
"max": 5000,
"currency": "GHS",
"period": "monthly"
},
"applicationDeadline": "2026-06-30T23:59:59.000Z",
"createdAt": "2026-04-01T09:00:00.000Z",
"updatedAt": "2026-04-01T09:00:00.000Z",
"poweredBy": {
"text": "Hiring powered by Prodigio",
"url": "https://prodigio.io"
}
}
Status codes
200Job found. Returns the full job object.401Missing or invalid API key.403API key not authorised for this domain. Use pk_test_ for local development.404Job not found or does not belong to your key.Upload a CV
Uploads a CV file to Prodigio storage. Call this before submitting an application and pass the returned URL in the application body. Accepts PDF and Word documents up to 10 MB.
/api/upload/cv?key={your-api-key}publicContent-Type
multipart/form-dataForm fields
fileFile, required
The CV file. Accepted: application/pdf, .doc, .docx. Max 10 MB.
Response
{
"url": "https://storage.prodigio.io/files/abc123.pdf",
"fileName": "john-doe-cv.pdf",
"fileSize": 245760,
"mimeType": "application/pdf",
"path": "files/abc123.pdf"
}
Upload achievement media
Uploads an achievement attachment (image or video). Call this for each achievement file before submitting the application, then pass the returned object in the achievements[n].attachment field. Max 5 MB.
/api/upload/achievement?key={your-api-key}publicContent-Type
multipart/form-dataForm fields
fileFile, required
Accepted: image/jpeg, image/png, image/gif, image/webp, video/mp4, video/webm.
Response
{
"url": "https://storage.prodigio.io/files/def456.png",
"fileName": "screenshot.png",
"fileSize": 204800,
"mimeType": "image/png",
"path": "files/def456.png"
}
Submit application
Submits a candidate application. Upload the CV first and include the returned URL in the cv field. Pass your API key in the x-api-key header.
/api/applicationspublicContent-Type
application/jsonAuth header
x-api-key: pk_live_...Required body fields
jobIdThe job ID from the list endpoint.
applicant.fullNameCandidate full name.
applicant.emailCandidate email.
applicant.phoneCandidate phone number.
cv.urlThe URL returned from the upload endpoint.
cv.fileNameOriginal file name.
cv.fileSizeFile size in bytes.
cv.mimeTypeMIME type of the uploaded file.
Request body example
{
"jobId": "abc123",
"applicant": {
"fullName": "Jane Smith",
"email": "jane@example.com",
"phone": "+233 20 000 0000",
"location": "Accra, Ghana",
"linkedin": "https://linkedin.com/in/janesmith"
},
"cv": {
"url": "https://storage.prodigio.io/files/xyz789.pdf",
"fileName": "jane-smith-cv.pdf",
"fileSize": 245760,
"mimeType": "application/pdf"
},
"coverLetter": "I am excited to apply...",
"achievements": [
{ "description": "Led a team of 5 engineers to ship the product on time", "attachment": null },
{ "description": "Reduced page load time by 40%", "attachment": null }
]
}
Response
{
"id": "app_xyz789",
"message": "Application submitted successfully",
"scoringError": null
}
Status codes
201Submission received. Returns id, message, and scoringError.400Missing required field, deadline passed, or duplicate submission.401Missing or invalid API key.403API key not authorised for this domain. Use pk_test_ for local development.404Company or listing not found.Express interest
Collects a candidate's contact details and area of interest without requiring an active job listing. Submissions appear in the Interests section of your dashboard, separate from applications.
/api/interestpublicAuth header
x-api-key: pk_live_...Required fields
nameCandidate full name.
emailCandidate email address.
phoneCandidate phone number.
Optional fields
linkedinLinkedIn profile URL.
locationCandidate location.
currentRoleCurrent job title.
experienceYears of experience (e.g. "3-5").
areaOfInterestArea of interest (e.g. "Engineering").
messageFree-text message from the candidate.
cvCV upload result object from the upload endpoint.
achievementsArray of achievement objects.
SDK usage
const prodigio = new Prodigio('pk_live_your_key_here');
const result = await prodigio.interest.submit({
name: 'Jane Smith',
email: 'jane@example.com',
phone: '+1 555 000 0000',
areaOfInterest: 'Engineering',
message: 'I would love to join your team.',
});
console.log(result.id);
Status codes
201Submitted successfully. Returns { id }.400Missing required field or invalid email.401Missing or invalid API key.403API key not authorised for this domain.Full integration example
Replace pk_live_your_key_here with your API key from Settings.
import { Prodigio } from '@prodigio-io/sdk';
const API_KEY = 'pk_live_your_key_here';
// 1. Add to your HTML where the badge should appear:
// <div data-prodigio-badge-anchor></div>
// 2. Initialise once at app root — badge is fully automatic
Prodigio.init({ key: API_KEY });
const prodigio = new Prodigio(API_KEY);
// 2. Fetch active jobs
async function getJobs() {
return prodigio.jobs.list();
}
// 3. Fetch a single job
async function getJob(jobId) {
return prodigio.jobs.get(jobId);
}
// 4. Upload a CV file (File object from <input type="file">)
async function uploadCV(file) {
return prodigio.upload.cv(file); // { url, fileName, fileSize, mimeType, path }
}
// 5. Submit an application
async function submitApplication({ jobId, applicant, cvFile, coverLetter }) {
const cv = await uploadCV(cvFile);
return prodigio.applications.submit({ jobId, applicant, cv, coverLetter });
}
Changelog
POST /api/interest endpoint and prodigio.interest.submit() SDK method. Collect candidate interest without an active job listing. Submissions appear in the Interests section of the dashboard.Prodigio.init() shows the badge only on the registered careers page and removes it on all other pages — no cleanup or framework-specific code needed. Added Prodigio.destroy(). Dev-mode warning added when the required meta tag is missing.Prodigio.init({ key, badgeToken? }) for automatic badge management. Paid tenants pass a badgeToken from their dashboard install snippet to suppress the badge with no visible flicker.Prodigio.badge() now accepts no arguments — falls back to built-in attribution. Prodigio.POWERED_BY exported as a static constant for direct access.Prodigio.badge(poweredBy) and Prodigio.meta() static helpers. Badge compliance is now verified via <meta name="prodigio-badge"> in the page head — required for reliable server-side detection.achievements type in SubmitApplicationParams — now correctly typed as { description: string; attachment?: UploadResult | null }[]. Added JSDoc on Job.createdAt clarifying it is an ISO 8601 string.npm install @prodigio-io/sdk). API key authentication (?key=pk_live_... and x-api-key header). The ?slug= parameter is now deprecated and will be removed 1 Jan 2027.poweredBy object. Free usage requires rendering this as a visible, clickable link.companyName. Applies to both list and detail endpoints.GET /api/jobs, GET /api/jobs/[id], POST /api/upload/cv, POST /api/applications. Full CORS support.