Get Job Status
Fetch the current status (and result, once finished) of an async verify job by its jobId. Use this to poll when you can't receive webhooks, or to reconcile a delivery you may have missed.
Endpoint
GET /verify/bank/jobs/:jobIdFull URL: https://api-partners.easyslip.com/v2/verify/bank/jobs/{jobId}
Authentication
Required. Uses HMAC-SHA256 with your branch UUID as X-API-Key. See Authentication Guide.
X-API-Key: YOUR_BRANCH_UUID
X-Timestamp: 1700000000
X-Nonce: 550e8400-e29b-41d4-a716-446655440000
X-Signature: HMAC_SHA256_SIGNATURERequest
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
jobId | string | Yes | The UUID returned by POST /verify/bank/async or /batch |
A job can only be read by the branch that created it. A jobId belonging to another branch returns the same 404 JOB_NOT_FOUND as a non-existent one (so job IDs can't be enumerated across branches).
Type Definitions
type JobStatus = 'queued' | 'processing' | 'retrying' | 'done' | 'failed';
// Response
interface JobStatusResponse {
success: true;
data: {
jobId: string;
status: JobStatus;
attempts: number; // processing attempts made so far
batchId?: string | null; // present when the job was submitted via /batch
result?: { status: 'success'; data: VerifyBankData } | { status: 'not_found'; data: unknown };
error?: unknown; // present when status is 'failed'
};
message: string;
}Job records are retained for 7 days after creation, then expire.
Terminal outcomes
donemeans verification finished withresult.status: "success"or"not_found". Exhausted not-found retries are not a failed job.failedmeans verification could not complete;error.code/messagematch the failure callback. Sending that callback successfully does not change the job todone.- Delivery failure preserves the verification error and adds
error.webhook: "failed"plus delivery details. Adonejob can also contain a delivery-only error. resultwraps{ status, data }; the verified slip is insideresult.data.
Examples
curl https://api-partners.easyslip.com/v2/verify/bank/jobs/550e8400-e29b-41d4-a716-446655440000 \
-H "X-API-Key: YOUR_BRANCH_UUID" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}"const getJob = async (jobId) => {
const path = `/verify/bank/jobs/${jobId}`;
const response = await fetch(`https://api-partners.easyslip.com/v2${path}`, {
method: 'GET',
headers: signRequest({ method: 'GET', path, apiKey: 'YOUR_BRANCH_UUID', secretKey: 'YOUR_SECRET_KEY' })
});
const result = await response.json();
if (!result.success) throw new Error(result.error.message);
return result.data; // { jobId, status, result?, ... }
};
// Poll until the job finishes
const waitForJob = async (jobId, { intervalMs = 2000, timeoutMs = 60000 } = {}) => {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const job = await getJob(jobId);
if (job.status === 'done') return job.result;
if (job.status === 'failed') throw new Error('Verification failed');
await new Promise((r) => setTimeout(r, intervalMs));
}
throw new Error('Timed out waiting for job');
};type JobStatus = 'queued' | 'processing' | 'retrying' | 'done' | 'failed';
async function getJob(jobId: string) {
const path = `/verify/bank/jobs/${jobId}`;
const response = await fetch(`https://api-partners.easyslip.com/v2${path}`, {
method: 'GET',
headers: signRequest({ method: 'GET', path, apiKey: process.env.EASYSLIP_API_KEY!, secretKey: process.env.EASYSLIP_SECRET_KEY! })
});
const result = await response.json();
if (!result.success) throw new Error(result.error?.message || 'Failed to fetch job');
return result.data as { jobId: string; status: JobStatus; attempts: number; result?: unknown; error?: unknown };
}function getJob(string $jobId): array
{
$path = "/verify/bank/jobs/{$jobId}";
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => "https://api-partners.easyslip.com/v2{$path}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
// Use signRequest() helper - see Authentication Guide
]
]);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
if (!$result['success']) {
throw new Exception($result['error']['message']);
}
return $result['data'];
}import requests
import os
def get_job(job_id: str) -> dict:
path = f'/verify/bank/jobs/{job_id}'
response = requests.get(
f'https://api-partners.easyslip.com/v2{path}',
headers=sign_request('GET', path, None, os.environ['EASYSLIP_API_KEY'], os.environ['EASYSLIP_SECRET_KEY'])
)
result = response.json()
if not result['success']:
raise Exception(result['error']['message'])
return result['data']Response
Queued / Processing (200)
{
"success": true,
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "processing",
"attempts": 1
},
"message": "OK"
}Done (200)
{
"success": true,
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "done",
"attempts": 1,
"result": {
"status": "success",
"data": {
"isDuplicate": false,
"rawSlip": {
"transRef": "68370160657749I376388B35",
"amount": {
"amount": 1500,
"local": {
"amount": 1500,
"currency": "THB"
}
},
"sender": {
"bank": {
"id": "004",
"short": "KBANK"
}
},
"receiver": {
"bank": {
"id": "014",
"short": "SCB"
}
}
}
}
}
},
"message": "OK"
}For a successful verification, result.data has the same shape as the synchronous POST /verify/bank data.
Failed (200)
{
"success": true,
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"status": "failed",
"attempts": 3,
"error": {
"code": "API_SERVER_ERROR",
"message": "External API service is temporarily unavailable"
}
},
"message": "OK"
}Error Responses
Job Not Found (404)
{
"success": false,
"error": {
"code": "JOB_NOT_FOUND",
"message": "Job 550e8400-e29b-41d4-a716-446655440000 not found"
}
}Returned both when the jobId doesn't exist and when it belongs to another branch.
Notes
- Status values:
queued→processing→done; a transient failure moves toretrying, and a permanently failed job ends atfailed. - Prefer webhooks for delivery; use polling as a fallback or reconciliation path.
- Job records expire 7 days after creation.