Using TypeScript? The
@nova-sdk/api package handles auth, retries, and types for you. Install it with npm install @nova-sdk/api.Prerequisites
API key from the Embed Portal (
sk_test_* for sandbox)A stable tenant external ID for your customer
Step 1: Generate clarification questions (optional)
curl -X POST 'https://embed.nova.dweet.com/v1/jobs/job-123/question-sets' \
-H 'Authorization: Bearer sk_test_your_key' \
-H 'X-Tenant-Id: acme-corp' \
-H 'Content-Type: application/json' \
-d '{
"jobContext": {
"jobTitle": "Senior Software Engineer",
"companyName": "Acme Corp",
"jobDescription": "We are looking for a Senior Software Engineer with 5+ years experience..."
}
}'
import { Nova } from '@nova-sdk/api';
const nova = new Nova({
apiKey: 'sk_test_your_key',
tenantId: 'acme-corp',
});
const { questionSet } = await nova.jobs.questionSets.create({
jobId: 'job-123',
body: {
jobContext: {
jobTitle: 'Senior Software Engineer',
companyName: 'Acme Corp',
jobDescription: 'We are looking for a Senior Software Engineer with 5+ years experience...',
},
},
});
Response
{
"questionSet": {
"id": "cmlz26ck2000awp61q9qcjcne",
"jobId": "job-123",
"questions": [
{
"id": "q1",
"selectionType": "single",
"question": "What level of seniority are you targeting?",
"options": ["Junior", "Mid", "Senior"],
"hint": null
}
],
"guidance": "Answer these questions to calibrate criteria generation.",
"expiresAt": "2026-12-14T11:30:45Z"
}
}
questionSet.id for the next step.
Step 2: Generate criteria
curl -X POST 'https://embed.nova.dweet.com/v1/jobs/job-123/criteria/generate' \
-H 'Authorization: Bearer sk_test_your_key' \
-H 'X-Tenant-Id: acme-corp' \
-H 'Content-Type: application/json' \
-d '{
"jobContext": {
"jobTitle": "Senior Software Engineer",
"companyName": "Acme Corp",
"jobDescription": "We are looking for a Senior Software Engineer with 5+ years experience..."
},
"questionSetId": "cmlz26ck2000awp61q9qcjcne",
"answers": [
{ "id": "q1", "value": "Senior" }
]
}'
const generation = await nova.jobs.criteria.generate.create({
jobId: 'job-123',
body: {
jobContext: {
jobTitle: 'Senior Software Engineer',
companyName: 'Acme Corp',
jobDescription: 'We are looking for a Senior Software Engineer with 5+ years experience...',
},
questionSetId: 'cmlz26ck2000awp61q9qcjcne',
answers: [
{ id: 'q1', value: 'Senior' },
],
},
});
Step 3: Submit a score request
curl -X POST 'https://embed.nova.dweet.com/v1/jobs/job-123/applications/app-456/scoring-jobs' \
-H 'Authorization: Bearer sk_test_your_key' \
-H 'X-Tenant-Id: acme-corp' \
-H 'Content-Type: application/json' \
-d '{
"resume": { "type": "url", "url": "https://storage.example.com/resumes/abc123.pdf" },
"jobDescription": "We are looking for a Senior Software Engineer with 5+ years experience..."
}'
const { scoringJob } = await nova.jobs.applications.scoringJobs.submit({
jobId: 'job-123',
applicationId: 'app-456',
body: {
resume: { type: 'url', url: 'https://storage.example.com/resumes/abc123.pdf' },
jobDescription: 'We are looking for a Senior Software Engineer with 5+ years experience...',
},
});
console.log(scoringJob.id); // 'scoring_job_id'
console.log(scoringJob.status); // 'pending'
Response
{
"scoringJob": {
"id": "scoring_job_id",
"status": "pending"
}
}
Step 4: Receive results
Use webhooks for real-time delivery, or poll viaGET /v1/jobs/{jobId}/applications/{applicationId}/scoring-jobs/{scoringJobId} as a fallback.
curl 'https://embed.nova.dweet.com/v1/jobs/job-123/applications/app-456/scoring-jobs/scoring_job_id' \
-H 'Authorization: Bearer sk_test_your_key' \
-H 'X-Tenant-Id: acme-corp'
const result = await nova.jobs.applications.scoringJobs.get({
jobId: 'job-123',
applicationId: 'app-456',
scoringJobId: 'scoring_job_id',
});
// Or get the latest score for an application directly
const latest = await nova.jobs.applications.getLatestScore({
jobId: 'job-123',
applicationId: 'app-456',
});