LandVerify API Documentation
Securely submit and track land verification requests via our REST API. All endpoints require authentication via an API key for enhanced security.
Authentication
Include your API key in the request header for all authenticated endpoints:
x-api-key: YOUR_API_KEY
Security Note: Never expose your API key in public repositories or client-side code.
1. Submit a Verification Request
Submit a new land verification request. Requires a valid user ID, address, and at least one file (Cloudinary URL).
Request Headers
Content-Type: application/json\nx-api-key: YOUR_API_KEY
Request Body
{
"address": "123 Main St, Lagos",
"files": ["https://res.cloudinary.com/demo/image/upload/sample.jpg"],
"userId": 32344386,
"lga": "Ikeja", // optional
"state": "Lagos", // optional
"landsize": "500sqm", // optional
"latitude": 6.5244, // optional
"longitude": 3.3792 // optional
}
Success Response (200)
{
"status": "SUBMITTED",
"findings": null,
"verificationId": "2e5ab633-ea41-4d99-809c-efbf1e1e6925",
"partnerId": 19
}
Example cURL
curl -X POST "https://app.landverify.ng/api/verification/submit" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"address": "123 Main St, Lagos",
"files": ["https://res.cloudinary.com/demo/image/upload/sample.jpg"],
"userId": 3386
}'
2. Get Verification Request Details
Fetches the details of a specific verification request by its ID.
Success Response (200)
{
"id": "2e5ab633-ea41-4d99-809c-efbf1e1e6925",
"address": "123 Main St, Lagos",
"landsize": "500sqm",
"latitude": 6.5244,
"longitude": 3.3792,
"lga": "Ikeja",
"state": "Lagos",
"status": "SUBMITTED"
}
Example cURL
curl "https://app.landverify.ng/api/verification-requests/2e5ab633-ea41-4d99-809c-efbf1e1e6925/requests" \
-H "x-api-key: YOUR_API_KEY"
3. Get Verification Findings (Polling Endpoint)
Fetches the current findings and status for a specific verification request.
Success Response (200)
{
"findings": {
"comments": "This property at 123 Main Street has been verified, you will have 480 characters here detailing the property findings and expert recommendations.",
"isRegisteredTitledVerified": true,
"isPropertyFreeOfAcquisition": false,
"DoesAddressMatchSurvey": false,
"erosionOrFloodRisk": false,
"locatedInMixedArea": true,
"suitableTopography": true,
// ...15+ other factors.
},
"status": "COMPLETED",
"updatedAt": "2025-06-26T12:00:00.000Z"
}
Example cURL
curl "https://app.landverify.ng/api/verification-requests/2e5ab633-ea41-4d99-809c-efbf1e1e6925/findings" \
-H "x-api-key: YOUR_API_KEY"
4. Rate Limiting
The /findings
endpoint is rate-limited to 30 requests per minute per API key.
Exceeding this limit will return a 429 Too Many Requests
error.
5. Error Handling
All endpoints return appropriate HTTP status codes and JSON error messages:
Client Errors (4xx)
400
- Bad Request404
- Not Found405
- Method Not Allowed429
- Too Many Requests
Server Errors (5xx)
500
- Internal Server Error
{
"message": "Findings not found for this verification request"
}
6. Polling Recommendations
Best Practices
- Polling Interval: Poll the
/findings
endpoint every 30–60 seconds to check for updates. - Stop Condition: Stop polling when
status
changes from"SUBMITTED"
or whenfindings
is no longernull
. - Error Handling: Implement exponential backoff for failed requests to avoid hitting rate limits.
7. Frontend Integration Examples
JavaScript (React Hook)
// JavaScript (React) polling for findings
import { useEffect, useState } from "react";
function useFindingsPolling(verificationId, apiKey, pollInterval = 30000) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
if (!verificationId || !apiKey) return;
let isMounted = true;
let intervalId;
const fetchFindings = async () => {
setLoading(true);
setError(null);
try {
const res = await fetch(
`/api/verification-requests/${verificationId}/findings`,
{
headers: { "x-api-key": apiKey },
}
);
if (!res.ok) throw new Error(`Error: ${res.status}`);
const result = await res.json();
if (isMounted) setData(result);
} catch (err) {
if (isMounted) setError(err.message || "Unknown error");
} finally {
if (isMounted) setLoading(false);
}
};
fetchFindings();
intervalId = setInterval(fetchFindings, pollInterval);
return () => {
isMounted = false;
clearInterval(intervalId);
};
}, [verificationId, apiKey, pollInterval]);
return { ...data, loading, error };
}
TypeScript (React Hook with Types)
// TypeScript (React) polling for findings
import { useEffect, useState } from "react";
interface FindingsResponse {
findings: any;
status: string;
updatedAt: string;
}
function useFindingsPolling(
verificationId: string,
apiKey: string,
pollInterval: number = 30000
): FindingsResponse & { loading: boolean; error: string | null } {
const [data, setData] = useState<FindingsResponse | null>(null);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
if (!verificationId || !apiKey) return;
let isMounted = true;
let intervalId: NodeJS.Timeout;
const fetchFindings = async () => {
setLoading(true);
setError(null);
try {
const res = await fetch(
`/api/verification-requests/${verificationId}/findings`,
{
headers: { "x-api-key": apiKey },
}
);
if (!res.ok) throw new Error(`Error: ${res.status}`);
const result: FindingsResponse = await res.json();
if (isMounted) setData(result);
} catch (err: any) {
if (isMounted) setError(err.message || "Unknown error");
} finally {
if (isMounted) setLoading(false);
}
};
fetchFindings();
intervalId = setInterval(fetchFindings, pollInterval);
return () => {
isMounted = false;
clearInterval(intervalId);
};
}, [verificationId, apiKey, pollInterval]);
return { ...data, loading, error };
}
Usage Tip: These hooks automatically handle polling, cleanup, and error states. Simply pass your verification ID and API key to start monitoring for results.
Need an API Key? You will need both a test and live API key to use the LandVerify API.
Please reach out to support@landverify.ng or +234 902 962 8530 to request keys.