Land-Listings.com API

The Land-Listings.com API allows approved Deluxe advertisers to integrate their property inventory with Land-Listings.com.

API access is managed by Land-Listings.com and is available to approved Deluxe advertisers. Contact Land-Listings.com to request API access.

What can I do with the API?

Export your inventory

Retrieve your own Land-Listings.com listings for use in your website, CRM, or another system.

Import and maintain listings

Send new listings to Land-Listings.com and keep property information updated automatically.

Manage listing media

Upload and manage listing images and PDF documents without entering them manually through the website.

Not a developer?
You can send this documentation to the person or company that manages your website, CRM, listing-management software, or other property system. The technical integration instructions begin below.

Overview

Base URL: https://api.land-listings.com/v1. HTTPS is required. API credentials belong to one Land-Listings account and can access or manage only listings, images, and documents owned by that account.

Read / Export API (stored scope: read_feed) allows the customer's system to retrieve their own Land-Listings inventory for use in an external website, CRM, or other system. Write / Import API (stored scope: write_feed) allows the customer's system to create and update listings on Land-Listings.com and manage supported listing images and documents. Normal full API access includes both permissions.

Integration walkthrough

  1. Receive the managed API credential issued for your approved Deluxe account.
  2. Authenticate every request with the Bearer token.
  3. POST a listing with your stable external_listing_id.
  4. Read LISTING_ID from data.id.
  5. Store the association between your external_listing_id and LISTING_ID.
  6. PATCH that LISTING_ID when an intentional listing change is needed.
  7. Upload an image and read IMAGE_ID from data.image.id.
  8. Use IMAGE_ID to set primary, reorder, or delete images.
  9. Upload a PDF and read DOCUMENT_ID from data.document.id.
  10. Use DOCUMENT_ID to update its description or delete it.

Authentication

Send the secret token using Bearer authentication. The compatibility header X-Api-Token is also supported. Keep credentials secret. The read_feed scope is the Read / Export API permission: it allows customers to pull their own Land-Listings inventory and reference data for use in an external website, CRM, or other system. The write_feed scope is the Write / Import API permission: it allows customers to push and maintain inventory on Land-Listings.com, including supported listings, images, and documents. GET /v1/listings requires read_feed or wildcard scope. Listing writes and every image/document route—including asset GET routes—require write_feed or wildcard scope and current Deluxe entitlement.

Authorization: Bearer YOUR_API_TOKEN
# Compatibility alternative:
X-Api-Token: YOUR_API_TOKEN

County taxonomy

GET /v1/counties?state=TX — Retrieve accepted canonical county values for one state.

County values come from Land-Listings' authoritative state/county taxonomy. This reference endpoint requires a valid managed API credential with read_feed or wildcard scope; current Deluxe entitlement is not required for this read-only lookup. The required state query value is a supported state or territory abbreviation. An invalid state returns HTTP 422 with validation_failed.

The response contains distinct canonical names in alphabetical order. Use one of these exact values for listing county. County identity is always state-specific; no county-table ID is exposed or accepted.

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/counties?state=TX"

HTTP/1.1 200 OK
{"success":true,"data":{"state":"TX","counties":["Anderson","Andrews","Angelina"]},"error":null,"meta":{"request_id":"...","version":"v1","resource":"counties","timestamp":"...","pagination":null},"links":{"self":"https://api.land-listings.com/v1/counties?state=TX"},"message":"Counties retrieved"}

Quick start — create a complete listing

This example creates a reasonably complete property using only fields supported by POST /v1/listings. Before submitting a county, retrieve Land-Listings' accepted canonical county values with GET /v1/counties?state=TX. Do not guess county spelling or formatting. The API validates county against state and stores the canonical Land-Listings value. Travis is used below as a canonical Texas example.

curl -X POST "https://api.land-listings.com/v1/listings" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "external_listing_id": "LANDVILLE-10025",
    "title": "40.25 Acres Near Austin, Texas",
    "description": "40.25 acres of rural land with road access and open views.",
    "price": 125000,
    "acres": 40.25,
    "owner_financing": true,
    "general_location": "Approximately 8 miles north of Austin",
    "address": "123 County Road 100",
    "city": "Austin",
    "state": "TX",
    "county": "Travis",
    "postal_code": "78701",
    "has_residence": false,
    "mls_number": "MLS-123456",
    "latitude": 30.3456,
    "longitude": -97.7431,
    "map_zoom": 14,
    "directions": "From Austin, travel north and follow County Road 100 to the property.",
    "custom_map_url": null,
    "video_url": null,
    "video_as_header": false
  }'

Successful creation

HTTP/1.1 201 Created
{
  "success": true,
  "data": {
    "id": 123,
    "external_listing_id": "LANDVILLE-10025",
    "status": "Active",
    "url": "https://land-listings.com/listing/123",
    "created_at": "2026-09-23T12:00:00+00:00",
    "updated_at": "2026-09-23T12:00:00+00:00"
  },
  "error": null,
  "meta": {
    "request_id": "EXAMPLE_REQUEST_ID",
    "version": "v1",
    "resource": "listings",
    "timestamp": "2026-09-23T12:00:00+00:00",
    "pagination": null,
    "idempotent_replay": false
  },
  "links": {"self": "https://api.land-listings.com/v1/listings"},
  "message": "Listing created"
}
data.id is your LISTING_ID. Save this LISTING_ID. You will use it to PATCH the listing, upload images, and upload documents. Also retain the association between your own external_listing_id and the returned LISTING_ID.

Next steps

  1. Create the listing and receive LISTING_ID.
  2. Upload images using LISTING_ID.
  3. Receive an IMAGE_ID for each uploaded image.
  4. Set the primary image or reorder images if desired.
  5. Upload PDFs using LISTING_ID.
  6. Receive a DOCUMENT_ID for each uploaded document.
  7. PATCH the listing whenever property information changes.

Listings

GET /v1/listings — List the authenticated account’s Active listings.

Query parameters: page defaults to 1; per_page defaults to 25 and is constrained to 1–100; updated_after accepts a parseable date/time such as ISO 8601 and includes listings updated at or after that time.

curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings?per_page=25&page=1&updated_after=2026-01-01T00:00:00Z"

{
  "success": true,
  "data": {
    "items": [{"id": 123, "title": "20 acres", "price": 75000, "slug": "20-acres", "is_active": true, "created_at": "...", "updated_at": "..."}],
    "total": 1, "per_page": 25, "current_page": 1, "last_page": 1
  },
  "error": null,
  "meta": {"request_id": "...", "version": "v1", "resource": "listings", "timestamp": "...", "pagination": {"total": 1, "per_page": 25, "current_page": 1, "last_page": 1}}
}
POST /v1/listings — Create and activate an owned listing under normal listing limits.
curl -X POST "https://api.land-listings.com/v1/listings" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" \
  -d '{"external_listing_id":"ABC123","title":"20 acres in Oklahoma","description":"Rural land with road access.","state":"OK","price":75000,"acres":20}'

external_listing_id is a customer-supplied, stable, case-sensitive synchronization identity scoped to your Land-Listings account. It is different from both mls_number and the Land-Listings data.id. Different API accounts may use the same external ID.

Repeated POST requests with the same external_listing_id for the same account return the existing listing unchanged. They do not create a duplicate or overwrite it. Use PATCH for intentional updates.

A new listing returns 201 Created. A retry returns 200 OK with the same resource and meta.idempotent_replay set to true. Read the Land-Listings identifier from data.id; use it as LISTING_ID in listing, image, and document routes.

New create — HTTP/1.1 201 Created
{
  "success": true,
  "data": {"id": 123, "external_listing_id": "ABC123", "status": "Active", "url": "https://land-listings.com/listing/123", "created_at": "...", "updated_at": "..."},
  "error": null,
  "meta": {"request_id": "...", "version": "v1", "resource": "listings", "timestamp": "...", "idempotent_replay": false}
}

Same external_listing_id retry — HTTP/1.1 200 OK
{
  "success": true,
  "data": {"id": 123, "external_listing_id": "ABC123", "status": "Active", "url": "https://land-listings.com/listing/123", "created_at": "...", "updated_at": "..."},
  "error": null,
  "meta": {"request_id": "...", "version": "v1", "resource": "listings", "timestamp": "...", "idempotent_replay": true}
}

Create field contract

FieldTypeRequirement / nullImportant validation
external_listing_idstringRequired, not null1–128 characters; trimmed; no control characters; case-sensitive identity
titlestringRequired, not nullNonblank; maximum 255
descriptionstringRequired, not nullNonblank; maximum 50,000 characters and 65,535 encoded bytes
priceintegerOptional, nullable0 or greater
acresnumberOptional, nullableGreater than 0; maximum two decimal places
owner_financingbooleanOptional; defaults falseBoolean
general_locationstringOptional, nullableMaximum 255
addressstringOptional, nullableMaximum 128
citystringOptional, nullableMaximum 128
statestringRequired, not nullSupported US state/territory abbreviation; normalized uppercase
countystringOptional, nullableMust match the listing state's canonical Land-Listings county taxonomy; surrounding whitespace and casing are normalized, and the canonical value is stored
postal_codestringOptional, nullableFive-digit ZIP or ZIP+4; leading zeroes preserved
has_residencebooleanOptional; defaults falseResidence details require true
bedroomsintegerOptional, nullable0–99; residence listings only
bathroomsintegerOptional, nullable0–99; residence listings only
half_bathroomsintegerOptional, nullable0–99; residence listings only
square_feetintegerOptional, nullable1–2,147,483,647; residence listings only
mls_numberstringOptional, nullableMaximum 128; not the synchronization key
latitudenumberOptional, nullable−90 to 90; latitude and longitude supplied together
longitudenumberOptional, nullable−180 to 180; latitude and longitude supplied together
map_zoomintegerOptional; defaults 180–20
directionsstringOptional, nullableMaximum 20,000
custom_map_urlstringOptional, nullableHTTPS Google Maps Embed, id.land, mapright.com, or uc.mapright.com URL
video_urlstringOptional, nullableHTTPS YouTube watch/embed/short URL or Vimeo video URL
video_as_headerbooleanOptional; defaults falseTrue requires a valid video URL

For maps and videos, supply a supported HTTPS URL. Do not send iframe or script HTML.

PATCH /v1/listings/{listing} — Partially update an owned listing.

Omitted fields remain unchanged. Explicit null clears nullable fields and explicit false sets a boolean false. The update fields are the create fields above except external_listing_id. Ownership, external identity, and status cannot be changed.

PATCH nullability: price, acres, general_location, address, city, county, postal_code, bedrooms, bathrooms, half_bathrooms, square_feet, mls_number, latitude, longitude, map_zoom, directions, custom_map_url, and video_url may be cleared with null. title, description, state, owner_financing, has_residence, and video_as_header cannot be null. Coordinates must resolve to either a complete pair or both null. Setting has_residence false clears residence details. Clearing video_url also makes video_as_header false.

PATCH fieldTypeNullable?Validation and explicit-null behavior
titlestringNoNonblank, maximum 255
descriptionstringNoNonblank, maximum 50,000 characters and 65,535 encoded bytes
priceintegerYes0 or greater; null clears
acresnumberYesGreater than 0, up to two decimals; null clears
owner_financingbooleanNoFalse explicitly disables owner financing
general_locationstringYesMaximum 255; null clears
addressstringYesMaximum 128; null clears
citystringYesMaximum 128; null clears
statestringNoSupported abbreviation, normalized uppercase
countystringYesMust resolve in the resulting state; canonical value stored; null clears
postal_codestringYesZIP or ZIP+4; null clears
has_residencebooleanNoFalse clears all four residence-detail fields
bedroomsintegerYes0–99 and resulting residence must be true; null clears
bathroomsintegerYes0–99 and resulting residence must be true; null clears
half_bathroomsintegerYes0–99 and resulting residence must be true; null clears
square_feetintegerYes1–2,147,483,647 and resulting residence must be true; null clears
mls_numberstringYesMaximum 128; null clears
latitudenumberYes−90 to 90; final coordinates must be paired; null clears only with null longitude
longitudenumberYes−180 to 180; final coordinates must be paired; null clears only with null latitude
map_zoomintegerYes0–20; null clears
directionsstringYesMaximum 20,000; null clears
custom_map_urlHTTPS URLYesSupported map provider only; null clears the custom map
video_urlHTTPS URLYesYouTube/Vimeo only; null removes seller video and disables header video
video_as_headerbooleanNoTrue requires a valid resulting video; false explicitly disables it

PATCH validates the final state/county pair. Supplying county resolves it against the resulting state. If state changes while county is omitted, an existing county is retained only when it remains valid in the new state; otherwise county is cleared. Arbitrary county strings and counties belonging only to another state return validation_failed without changing the listing.

The API rejects external_listing_id, user_id, ownership, status, membership, billing, promotion, timestamp, generated-video, and other internal fields on PATCH.

curl -X PATCH "https://api.land-listings.com/v1/listings/LISTING_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" \
  -d '{"price":72500,"owner_financing":false}'

HTTP/1.1 200 OK
{"success":true,"data":{"id":123,"external_listing_id":"ABC123","status":"Active","url":"https://land-listings.com/listing/123","created_at":"...","updated_at":"..."},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"...","idempotent_replay":false}}

Images

Images use one multipart upload per request. Field name: image. JPEG/JPG, PNG, and GIF are supported. A Deluxe listing may store 100 images.

Recommended file size: 5 MB or less per image. Smaller optimized images upload faster and reduce processing and transfer time. This is guidance, not a validation limit; customers should not intentionally target the maximum.
Technical maximum: 10,485,760 bytes per image.
  • GET /v1/listings/{listing}/images
  • POST /v1/listings/{listing}/images
  • DELETE /v1/listings/{listing}/images/{image}
  • PATCH /v1/listings/{listing}/images/{image}/primary
  • PATCH /v1/listings/{listing}/images/order
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings/LISTING_ID/images"

curl -X POST "https://api.land-listings.com/v1/listings/LISTING_ID/images" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -F "image=@property.jpg"

curl -X PATCH -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings/LISTING_ID/images/IMAGE_ID/primary"

curl -X PATCH "https://api.land-listings.com/v1/listings/LISTING_ID/images/order" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" \
  -d '{"image_ids":[IMAGE_ID]}'

curl -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings/LISTING_ID/images/IMAGE_ID"

Reordering requires the complete, duplicate-free collection of image IDs belonging to that listing.

Image list responses return data.items, data.count, and data.maximum. Each item contains id, listing_id, primary, display_order, and urls for large, medium, small, and thumbnail variants. Upload returns the new item at data.image; use data.image.id as IMAGE_ID. Primary returns the updated image item. Reorder returns the complete image-list response. Delete returns data.id, data.listing_id, and data.deleted=true.

Image response examples

GET list — 200 OK
{"success":true,"data":{"items":[{"id":44,"listing_id":123,"primary":true,"display_order":1,"urls":{"large":"...","medium":"...","small":"...","thumbnail":"..."}}],"count":1,"maximum":100},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

POST upload — 201 Created
{"success":true,"data":{"image":{"id":44,"listing_id":123,"primary":false,"display_order":1,"urls":{"large":"...","medium":"...","small":"...","thumbnail":"..."}},"count":1,"maximum":100},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

PATCH primary — 200 OK
{"success":true,"data":{"id":44,"listing_id":123,"primary":true,"display_order":1,"urls":{"large":"...","medium":"...","small":"...","thumbnail":"..."}},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

PATCH order — 200 OK
{"success":true,"data":{"items":[{"id":44,"listing_id":123,"primary":true,"display_order":1,"urls":{"large":"...","medium":"...","small":"...","thumbnail":"..."}}],"count":1,"maximum":100},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

DELETE — 200 OK
{"success":true,"data":{"id":44,"listing_id":123,"deleted":true},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

Documents

Documents use one multipart upload per request. Field name: document; optional field description. PDF is the only supported type, descriptions are limited to 250 characters, and a Deluxe listing may store five documents.

Recommended file size: 3 MB or less per PDF. Customers should optimize PDFs where practical rather than targeting the maximum. This recommendation is guidance, not a validation limit.
Technical maximum: 6,000,000 bytes per PDF.
  • GET /v1/listings/{listing}/documents
  • POST /v1/listings/{listing}/documents
  • PATCH /v1/listings/{listing}/documents/{document}
  • DELETE /v1/listings/{listing}/documents/{document}
curl -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings/LISTING_ID/documents"

curl -X POST "https://api.land-listings.com/v1/listings/LISTING_ID/documents" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -F "document=@survey.pdf" -F "description=Property survey"

curl -X PATCH "https://api.land-listings.com/v1/listings/LISTING_ID/documents/DOCUMENT_ID" \
  -H "Authorization: Bearer YOUR_API_TOKEN" -H "Content-Type: application/json" \
  -d '{"description":"Updated survey"}'

curl -X DELETE -H "Authorization: Bearer YOUR_API_TOKEN" \
  "https://api.land-listings.com/v1/listings/LISTING_ID/documents/DOCUMENT_ID"

Document list responses return data.items, data.count, and data.maximum. Each item contains id, listing_id, description, type, public url, created_at, and updated_at. Upload returns the new item at data.document; use data.document.id as DOCUMENT_ID. Description update returns the updated document item. Delete returns data.id, data.listing_id, and data.deleted=true.

Document response examples

GET list — 200 OK
{"success":true,"data":{"items":[{"id":77,"listing_id":123,"description":"Property survey","type":"pdf","url":"...","created_at":"...","updated_at":"..."}],"count":1,"maximum":5},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

POST upload — 201 Created
{"success":true,"data":{"document":{"id":77,"listing_id":123,"description":"Property survey","type":"pdf","url":"...","created_at":"...","updated_at":"..."},"count":1,"maximum":5},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

PATCH description — 200 OK
{"success":true,"data":{"id":77,"listing_id":123,"description":"Updated survey","type":"pdf","url":"...","created_at":"...","updated_at":"..."},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

DELETE — 200 OK
{"success":true,"data":{"id":77,"listing_id":123,"deleted":true},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}

Responses & Errors

Successful resource responses use the standard envelope below. Endpoint examples above show the exact endpoint-specific data fields. Every standard response also contains meta.pagination (null for non-paginated responses), links.self, and the operation’s message. Timestamps and generated URLs are abbreviated with ... only for readability. Some authentication and rate-limit failures intentionally use a smaller response.

{"success":true,"data":{},"error":null,"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"...","pagination":null},"links":{"self":"https://api.land-listings.com/v1/..."},"message":"Operation completed"}

{"success":false,"data":{},"error":{"code":"validation_failed","message":"The request data is invalid.","details":{}},"meta":{"request_id":"...","version":"v1","resource":"listings","timestamp":"..."}}
StatusConditionActual code/response
401Missing or invalid credentialmissing_token or invalid_token is retained in safe request logs; response message identifies missing/invalid token
403Write scope missinginsufficient_scope
403Current Deluxe requireddeluxe_required
404Missing or non-owned resourceresource_not_found
409External ID belongs to a soft-deleted listingexternal_listing_id_retired
409Unexpected create integrity conflictintegrity_failure
422Request validationvalidation_failed
422Listing could not be activatedlisting_activation_failed
422Unsafe image dimensionsunsafe_image_dimensions
422Image capacity reachedimage_limit_reached
422Invalid/incomplete image reorderinvalid_image_order
422Document capacity reacheddocument_limit_reached
500Safe internal listing failureinternal_error
500Safe internal asset failureimage_operation_failed or document_operation_failed
429Client rate limit{"message":"Too Many Attempts."} plus Retry-After

Limits

  • 120 requests per minute per API client
  • 100 images per Deluxe listing; recommended file size 5 MB or less; technical maximum 10,485,760 bytes per image
  • 5 PDF documents per Deluxe listing; recommended file size 3 MB or less; technical maximum 6,000,000 bytes per PDF

© 2026 All Right Reserved