LandVerify Business
Business API

LandVerify Business API

Embed professional land verification directly into your platform. Two endpoints. One API key. Results in under 24 hours.

Base URLhttps://app.landverify.ng
Authx-api-key header

Quick Start

1
๐Ÿ”‘

Get API Key

Find it in your Business Dashboard under Settings โ†’ API

2
๐Ÿ“ค

Submit Verification

POST to /api/business/verify with address + type

3
๐Ÿ”„

Poll for Results

GET /findings every 30 s until status is COMPLETED

Authentication

Every request must include your business API key as a header. You can find and rotate your key in the Business Dashboard โ†’ Settings โ†’ API Keys.

x-api-key: lv_biz_xxxxxxxxxxxxxxxxxxxxxxxx
Security: Keep your API key server-side only. Never expose it in frontend code, git repositories, or client-facing apps.

Verification Types

The API supports two types of verification, controlled by the type field. Each type has its own quota tracked separately on your account.

๐Ÿ“‹

Basic Verification

type: "basic"

Address + government record cross-check. Ideal for quick title confirmation, pre-deal screening, or high-volume workflows.

โœ“address - required
โ—‹state, lga, landsize, latitude, longitude - optional
- files - not used
Returns: findings object
๐Ÿ”ฌ

Full Verification

type: "full"

Everything in Basic, plus forensic AI document analysis. Required for mortgage due diligence, legal conveyancing, and compliance workflows.

โœ“address - required
โœ“files - required (min. 1 document)
โ—‹state, lga, landsize, latitude, longitude - optional
Returns: findings + documentIntegrity

File Upload (Full Verification)

Files must be sent as Base64 data URIs or public HTTPS URLs. Accepted document types: title deeds, survey plans, receipts, and any property document in PNG, JPG, JPEG, or PDF format.

Max size
10 MB per file
Formats
PNG ยท JPG ยท JPEG ยท PDF
Min files
1 (no maximum)

Converting files to Base64

function fileToBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);  // "data:image/png;base64,..."
    reader.onerror = reject;
  });
}

// Convert multiple files before submitting full verification
const prepareFiles = async (fileList) => {
  return Promise.all(Array.from(fileList).map(fileToBase64));
};

1 - Submit a Verification

POST/api/business/verify

Submits a new verification request against your business quota. On success you receive a verificationId -keep it to poll for results.

Request body

FieldTypeRequiredDescription
typestringAlways"basic" or "full"
addressstringAlwaysFull property address to verify
filesstring[]Full onlyBase64 data URIs or public URLs of property documents
statestringOptionalState name (e.g. Lagos)
lgastringOptionalLocal Government Area
landsizestringOptionalSize string e.g. "500sqm"
latitudenumberOptionalGPS latitude
longitudenumberOptionalGPS longitude

Basic verification - minimal request

curl -X POST "https://app.landverify.ng/api/business/verify" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_BUSINESS_API_KEY" \
  -d '{
    "type": "basic",
    "address": "14 Adeola Odeku Street, Victoria Island, Lagos"
  }'

Basic verification - with optional fields

curl -X POST "https://app.landverify.ng/api/business/verify" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_BUSINESS_API_KEY" \
  -d '{
    "type": "basic",
    "address": "14 Adeola Odeku Street, Victoria Island, Lagos",
    "state": "Lagos",
    "lga": "Eti-Osa",
    "landsize": "600sqm",
    "latitude": 6.4281,
    "longitude": 3.4219
  }'

Full verification - with documents

curl -X POST "https://app.landverify.ng/api/business/verify" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_BUSINESS_API_KEY" \
  -d '{
    "type": "full",
    "address": "14 Adeola Odeku Street, Victoria Island, Lagos",
    "files": [
      "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQ...",
      "data:application/pdf;base64,JVBERi0xLjQK..."
    ],
    "state": "Lagos",
    "lga": "Eti-Osa",
    "landsize": "600sqm",
    "latitude": 6.4281,
    "longitude": 3.4219
  }'

Success response (201)

{
  "success": true,
  "verificationId": "a7f3c891-12bd-4e67-9053-cde72b1a3e88",
  "type": "basic",
  "status": "SUBMITTED",
  "quota": {
    "used": 4,
    "limit": 20,
    "remaining": 16
  },
  "submittedAt": "2025-10-05T09:15:00.000Z",
  "message": "Verification submitted successfully. Poll the findings endpoint for results."
}

Response fields

verificationId-UUID to poll for results
type-basic or full
status-Always SUBMITTED on creation
quota.used-Verifications used this period
quota.limit-Your plan's quota for this type
quota.remaining-How many you have left

2 - Get Verification Findings

GET/api/business/verify/:verificationId/findings

Poll this endpoint with the verificationId from Step 1 to check for results. Verification typically completes within a few hours.

โš ๏ธ
Rate limit: 30 requests per minute per API key. Poll every 30โ€“60 seconds to stay well within limits.

Example request

curl "https://app.landverify.ng/api/business/verify/a7f3c891-12bd-4e67-9053-cde72b1a3e88/findings" \
  -H "x-api-key: YOUR_BUSINESS_API_KEY"

Response - in progress

{
  "verificationId": "a7f3c891-12bd-4e67-9053-cde72b1a3e88",
  "type": "basic",
  "status": "IN_PROGRESS",
  "findings": null,
  "documentIntegrity": null,
  "updatedAt": "2025-10-05T09:20:00.000Z"
}

Response - basic verification complete

When complete, findings is populated. For basic verifications, documentIntegrity is always null.

{
  "verificationId": "a7f3c891-12bd-4e67-9053-cde72b1a3e88",
  "type": "basic",
  "status": "COMPLETED",
  "findings": {
    "comments": "Property is verified. Clean title with no encumbrances detected. Suitable for residential development pending standard zoning approvals.",
    "isRegisteredTitledVerified": true,
    "isPropertyFreeOfAcquisition": true,
    "DoesAddressMatchSurvey": true,
    "erosionOrFloodRisk": false,
    "locatedInMixedArea": true,
    "suitableTopography": true
  },
  "documentIntegrity": null,
  "updatedAt": "2025-10-05T11:45:00.000Z"
}

Response - full verification complete

Full verifications additionally return a documentIntegrity object with the AI forensic analysis of your submitted documents.

{
  "verificationId": "b9d2e712-44ca-4f81-a017-8fa913c2d501",
  "type": "full",
  "status": "COMPLETED",
  "findings": {
    "comments": "Property verified with full document review. Title is valid and unencumbered.",
    "isRegisteredTitledVerified": true,
    "isPropertyFreeOfAcquisition": true,
    "DoesAddressMatchSurvey": true,
    "erosionOrFloodRisk": false,
    "locatedInMixedArea": true,
    "suitableTopography": true
  },
  "documentIntegrity": {
    "overallScore": 94,
    "verdict": "AUTHENTIC",
    "documentsAnalysed": 2,
    "issues": [],
    "checks": {
      "stampDutyPresent": true,
      "signatureConsistency": true,
      "dateSequenceValid": true,
      "surveyNumberMatchesTitle": true,
      "ownerNameConsistency": true,
      "documentAgeConsistent": true
    },
    "riskFlags": []
  },
  "updatedAt": "2025-10-05T12:00:00.000Z"
}

documentIntegrity fields explained

overallScorenumber0โ€“100 authenticity score across all submitted documents
verdictstringAUTHENTIC | SUSPICIOUS | FRAUDULENT
documentsAnalysednumberCount of documents processed
issuesstring[]Human-readable descriptions of detected problems
checksobjectBoolean results for each forensic check (see example above)
riskFlagsstring[]High-severity flags requiring immediate attention

Polling best practices

โœ“Poll every 30โ€“60 seconds (not faster)
โœ“Stop when status === "COMPLETED" and findings !== null
โœ“Set a 30-minute maximum timeout and surface a pending message to your users
โœ“Use exponential backoff if you receive 429 (rate limit) responses

Complete JavaScript Example

A production-ready helper that submits a verification and polls until complete:

// JavaScript -submit a basic verification
const verifyProperty = async (address) => {
  const response = await fetch(
    "https://app.landverify.ng/api/business/verify",
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-api-key": process.env.LANDVERIFY_API_KEY,
      },
      body: JSON.stringify({ type: "basic", address }),
    }
  );

  if (!response.ok) {
    const err = await response.json();
    throw new Error(err.message);
  }

  const { verificationId } = await response.json();
  return verificationId;
};

// Poll until complete (max 30 min)
const waitForFindings = async (verificationId) => {
  const POLL_INTERVAL = 30_000; // 30 seconds
  const TIMEOUT = 30 * 60 * 1000; // 30 minutes
  const start = Date.now();

  while (Date.now() - start < TIMEOUT) {
    await new Promise(r => setTimeout(r, POLL_INTERVAL));

    const res = await fetch(
      `https://app.landverify.ng/api/business/verify/${verificationId}/findings`,
      { headers: { "x-api-key": process.env.LANDVERIFY_API_KEY } }
    );

    const data = await res.json();

    if (data.status === "COMPLETED" && data.findings) {
      return data; // { findings, documentIntegrity, status }
    }
  }

  throw new Error("Verification timed out after 30 minutes.");
};

// Usage
const id = await verifyProperty("14 Adeola Odeku St, VI, Lagos");
const result = await waitForFindings(id);
console.log(result.findings.comments);

Error Reference

All errors follow a consistent shape with a machine-readable error code and a human-readable message you can display directly to users.

Client errors (4xx)

400VALIDATION_ERRORMissing/invalid field
401UNAUTHORIZEDBad or missing API key
403QUOTA_EXCEEDEDPlan quota exhausted
404NOT_FOUNDUnknown verificationId
429RATE_LIMITEDToo many requests

Server errors (5xx)

500INTERNAL_ERRORUnexpected server error
503SERVICE_UNAVAILABLETemporary outage
// 400 - Missing required field
{
  "success": false,
  "error": "VALIDATION_ERROR",
  "message": "address is required for all verification types.",
  "field": "address"
}

// 400 -Files missing for full verification
{
  "success": false,
  "error": "VALIDATION_ERROR",
  "message": "files are required for full verification. Please provide at least one document (title deed, survey plan, etc.).",
  "field": "files"
}

// 400 - Invalid verification type
{
  "success": false,
  "error": "VALIDATION_ERROR",
  "message": "type must be either 'basic' or 'full'.",
  "field": "type"
}

// 401 - Bad API key
{
  "success": false,
  "error": "UNAUTHORIZED",
  "message": "Invalid or inactive API key. Check your key in the Business Dashboard."
}

// 403 - Quota exhausted
{
  "success": false,
  "error": "QUOTA_EXCEEDED",
  "message": "Your basic verification quota is exhausted (20/20 used). Contact support to top up.",
  "quota": { "used": 20, "limit": 20, "remaining": 0 }
}

// 404 - Verification not found
{
  "success": false,
  "error": "NOT_FOUND",
  "message": "Verification 'xyz' not found or does not belong to your account."
}

// 429 - Rate limited
{
  "success": false,
  "error": "RATE_LIMITED",
  "message": "Too many requests. Please wait before retrying.",
  "retryAfterSeconds": 30
}

Ready to integrate?

Your API key is in your Business Dashboard. Stuck on something? Our team responds within 2 business hours.