Freelance Verification
Verify a freelancer's certificate and its status using their National ID and certificate number.
Goal: Confirm a freelancer's certificate is authentic and active, and retrieve the freelancer and certificate details.
Estimated time: 15 minutes
Prerequisites
- Sandbox credentials and an access token
- The freelancer's National ID and certificate number
When to use
- Freelance marketplaces running background checks
- Recruitment platforms vetting candidates
- Any workflow that must confirm a professional credential before engagement
What it returns
Freelancer Verification has two endpoints:
| Endpoint | Method and URL | Use it when |
|---|---|---|
| Certificate Details | POST /api/v2.0/av/FreelancerVerification/CertificateDetails | You need the freelancer's details and the full certificate record |
| Certificate Status | GET /api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber={certificateNumber} | You only need the certificate's current status |
The Certificate Details endpoint requires the freelancer's nationalId and certificateNumber. The Certificate Status endpoint only requires certificateNumber as a query parameter.
| Endpoint | Response |
|---|---|
| Certificate Details | Freelancer name in English and Arabic, gender, National ID, certificate status, issue and expiry dates, certificate number, specialization, and category |
| Certificate Status | Current status, issue date, expiry date, license number, and revocation or cancellation date when applicable |
Certificate status can be Active, Revoked, Rejected, Expired, Canceled, or Pending.
Integration summary
Authenticate
Obtain a Bearer access token from your API credentials.
Get certificate details
Use this endpoint when you need the full freelancer and certificate record:
POST /api/v2.0/av/FreelancerVerification/CertificateDetails
curl -X POST https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "nationalId": "1106972886", "certificateNumber": "FL-669844156" }'const res = await fetch(
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails",
{
method: "POST",
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
nationalId: "1106972886",
certificateNumber: "FL-669844156",
}),
},
);
const data = await res.json();import requests
res = requests.post(
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails",
headers={
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
},
json={
"nationalId": "1106972886",
"certificateNumber": "FL-669844156",
},
)
data = res.json()import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
String body = """
{ "nationalId": "1106972886", "certificateNumber": "FL-669844156" }
""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails"))
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String result = response.body();using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using var client = new HttpClient();
var request = new HttpRequestMessage(
HttpMethod.Post,
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails");
request.Headers.Add("Authorization", $"Bearer {accessToken}");
request.Content = new StringContent(
"{ \"nationalId\": \"1106972886\", \"certificateNumber\": \"FL-669844156\" }",
Encoding.UTF8,
"application/json");
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();package main
import (
"bytes"
"io"
"net/http"
)
payload := []byte(`{ "nationalId": "1106972886", "certificateNumber": "FL-669844156" }`)
req, err := http.NewRequest(
http.MethodPost,
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/CertificateDetails",
bytes.NewReader(payload),
)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)Get the certificate status
Use this endpoint when you only need the certificate's current status:
GET /api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber={certificateNumber}
curl -X GET "https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber=FL-669844156" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"const certificateNumber = "FL-669844156";
const url = new URL(
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus",
);
url.searchParams.set("certificateNumber", certificateNumber);
const res = await fetch(url, {
headers: {
Authorization: `Bearer ${accessToken}`,
},
});
const data = await res.json();import requests
res = requests.get(
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus",
headers={
"Authorization": f"Bearer {access_token}",
},
params={
"certificateNumber": "FL-669844156",
},
)
data = res.json()import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber=FL-669844156"))
.header("Authorization", "Bearer " + accessToken)
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String body = response.body();using System;
using System.Net.Http;
using System.Threading.Tasks;
using var client = new HttpClient();
var request = new HttpRequestMessage(
HttpMethod.Get,
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber=FL-669844156");
request.Headers.Add("Authorization", $"Bearer {accessToken}");
var response = await client.SendAsync(request);
var body = await response.Content.ReadAsStringAsync();package main
import (
"io"
"net/http"
)
req, err := http.NewRequest(
http.MethodGet,
"https://sandbox.sparefinancial.sa/api/v2.0/av/FreelancerVerification/GetCertificateStatus?certificateNumber=FL-669844156",
nil,
)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+accessToken)
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)Use the certificate status
Treat only Active certificates as valid. A different status means the certificate should be blocked or reviewed.
Handle request errors separately: invalid input (400), expired or invalid token (401), certificate not found (404), and a National ID that does not match the certificate (412).
Sandbox testing
Use these National ID and certificate combinations to exercise the success and error paths.
Successful
| National ID | Certificate number |
|---|---|
| 1106972886 | FL-669844156 |
| 1000000000 | FL-511414201 |
Error scenarios
| National ID | Certificate number | Result |
|---|---|---|
| 123456 | FL-469744146 | 400 National ID invalid |
| 1000000000 | 1234 | 400 certificate number invalid |
| 1000000000 | FL-250336300 | 404 certificate number not found |
| 1000000000 | FL-566558999 | 412 National ID does not match certificate |
Key takeaways
- Use Certificate Details when you need the freelancer and certificate record.
- Use Certificate Status when you only need the certificate's current status.
- Treat only
Activecertificates as valid. Other statuses should block the request or trigger a review.