Build with LayrQ
Documentation
From an AI-generated layer specification to a production viewport query.
Agent contract
Give any coding agent the complete rules
Copy the reference or the ready-made prompt into ChatGPT, Claude, Gemini, or another LLM. The model can then produce a valid LayrQ layer definition without needing GIS-specific knowledge.
What the JSON controlsLayer identity and titleOne point, line, or polygon familyPublic, private, or unlisted accessTyped and validated properties
1. Describe the layer you want
Mention what each feature represents, its geometry, the properties to keep, and who should be able to read it.
“Create a private line layer for water mains. Each feature needs a required asset ID, material chosen from PVC, Copper, and Steel, installation date, diameter in inches, and an in-service boolean.”
2. Paste this ready-to-use LLM prompt
Replace the bracketed application description. The full contract is already included below it.
Prompt template
You are designing a LayrQ spatial layer. Read the LayrQ agent reference below, then return exactly one valid layer specification JSON object. Do not return Markdown or commentary. Use one geometry family, lowercase snake_case names, and only supported field types. My application needs: [DESCRIBE THE DATA, GEOMETRY, FIELDS, AND VISIBILITY HERE] LAYRQ AGENT REFERENCE: [the complete reference shown in section 4]
3. Expected layer specification
Paste the generated object into New layer → JSON specification.
Valid JSON
{
"name": "inspection_assets",
"title": "Inspection Assets",
"geometry": "line",
"visibility": "private",
"fields": {
"asset_id": {
"type": "string",
"required": true
},
"condition": {
"type": "enum",
"values": [
"Good",
"Fair",
"Poor"
]
},
"inspection_date": {
"type": "date"
},
"needs_repair": {
"type": "boolean"
},
"length_m": {
"type": "number"
}
}
}4. Full LayrQ agent reference
This machine-readable contract includes the schema, geometry compatibility, field rules, feature format, query contract, limits, and AI instructions.
layrq-agent-spec.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://www.layrq.com/layrq-agent-spec.json",
"title": "LayrQ agent reference",
"version": "1.0.0",
"purpose": "Create one schema-constrained spatial layer and its live API from one JSON object.",
"canonicalBaseUrl": "https://www.layrq.com",
"rules": {
"oneGeometryFamilyPerLayer": true,
"mixedGeometry": false,
"geometryCollection": false,
"coordinateReferenceSystem": "EPSG:4326",
"coordinateOrder": [
"longitude",
"latitude"
],
"maximumFields": 100,
"maximumVerticesPerGeometry": 10000,
"fieldNames": "lowercase snake_case; start with a letter; contain only letters, numbers, and underscores",
"featureProperties": "Every property must be declared in fields. Required fields must be present and non-null.",
"polygonValidity": "Polygons must pass PostGIS ST_IsValid. LayrQ returns the validation reason and never silently repairs geometry."
},
"layerSpecificationSchema": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"title",
"geometry",
"visibility",
"fields"
],
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,62}$",
"description": "Stable machine name. Use lowercase snake_case."
},
"title": {
"type": "string",
"minLength": 1,
"maxLength": 120,
"description": "Human-readable layer title."
},
"geometry": {
"type": "string",
"enum": [
"point",
"line",
"polygon"
],
"description": "Geometry family. Singular and matching multipart GeoJSON variants are accepted."
},
"visibility": {
"type": "string",
"enum": [
"public",
"private",
"unlisted"
],
"description": "Public is internet-readable. Private and unlisted layers require an owner session or API key; unlisted layers are also omitted from public listings."
},
"fields": {
"type": "object",
"maxProperties": 100,
"propertyNames": {
"pattern": "^[a-z][a-z0-9_]{0,62}$"
},
"additionalProperties": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"required": [
"type"
],
"properties": {
"type": {
"enum": [
"string",
"number",
"boolean",
"date"
]
},
"required": {
"type": "boolean",
"default": false
}
}
},
{
"type": "object",
"additionalProperties": false,
"required": [
"type",
"values"
],
"properties": {
"type": {
"const": "enum"
},
"required": {
"type": "boolean",
"default": false
},
"values": {
"type": "array",
"minItems": 1,
"maxItems": 100,
"uniqueItems": true,
"items": {
"type": "string",
"minLength": 1,
"maxLength": 120
}
}
}
}
]
}
}
}
},
"geometryCompatibility": {
"point": [
"Point",
"MultiPoint"
],
"line": [
"LineString",
"MultiLineString"
],
"polygon": [
"Polygon",
"MultiPolygon"
]
},
"fieldTypes": {
"string": {
"jsonType": "string",
"example": "Bridge 12"
},
"number": {
"jsonType": "number",
"example": 98.5
},
"boolean": {
"jsonType": "boolean",
"example": true
},
"date": {
"jsonType": "string",
"format": "YYYY-MM-DD",
"example": "2026-07-29"
},
"enum": {
"jsonType": "string",
"rule": "Value must exactly match one entry in values.",
"example": "Good"
}
},
"layerSpecificationExample": {
"name": "inspection_assets",
"title": "Inspection Assets",
"geometry": "line",
"visibility": "private",
"fields": {
"asset_id": {
"type": "string",
"required": true
},
"condition": {
"type": "enum",
"values": [
"Good",
"Fair",
"Poor"
]
},
"inspection_date": {
"type": "date"
},
"needs_repair": {
"type": "boolean"
},
"length_m": {
"type": "number"
}
}
},
"featureInput": {
"format": "GeoJSON Feature",
"schema": {
"type": "object",
"additionalProperties": false,
"required": [
"type",
"geometry",
"properties"
],
"properties": {
"type": {
"const": "Feature"
},
"geometry": {
"type": "object",
"required": [
"type",
"coordinates"
],
"properties": {
"type": {
"enum": [
"Point",
"MultiPoint",
"LineString",
"MultiLineString",
"Polygon",
"MultiPolygon"
]
},
"coordinates": {
"description": "Valid GeoJSON coordinates in EPSG:4326 longitude-latitude order."
}
}
},
"properties": {
"type": "object",
"description": "Keys and value types must match the layer fields schema."
}
}
},
"example": {
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[
-97.7431,
30.2672
],
[
-97.741,
30.269
]
]
},
"properties": {
"asset_id": "A-1001",
"condition": "Good",
"inspection_date": "2026-07-29",
"needs_repair": false,
"length_m": 284.6
}
}
},
"createLayerRequest": {
"method": "POST",
"path": "/api/v1/layers",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_LAYRQ_API_KEY_OR_SUPABASE_ACCESS_TOKEN"
},
"body": "One object that validates against layerSpecificationSchema."
},
"successfulLayerResponse": {
"layerId": "lyr_123",
"featuresUrl": "https://www.layrq.com/api/v1/layers/lyr_123/features",
"geojsonUrl": "https://www.layrq.com/api/v1/layers/lyr_123.geojson",
"csvUrl": "https://www.layrq.com/api/v1/layers/lyr_123.csv",
"tileUrl": "https://www.layrq.com/api/v1/layers/lyr_123/tiles/{z}/{x}/{y}.pbf",
"schemaUrl": "https://www.layrq.com/api/v1/layers/lyr_123",
"arcgisServiceUrl": "https://www.layrq.com/arcgis/rest/services/lyr_123/FeatureServer"
},
"queryContract": {
"path": "/api/v1/layers/{layerId}/features",
"parameters": {
"bbox": "minLongitude,minLatitude,maxLongitude,maxLatitude",
"limit": "Default 100; maximum 1000.",
"cursor": "Opaque nextCursor from the previous response.",
"fields": "Comma-separated property names.",
"filter.FIELD": "Equality filter.",
"filter.FIELD__OPERATOR": "OPERATOR is neq, gt, gte, lt, or lte."
},
"paginationRule": "Continue until pagination.hasMore is false. Never invent, decode, or modify the cursor.",
"example": "/api/v1/layers/lyr_123/features?bbox=-98,29,-96,31&limit=100&fields=asset_id,condition&filter.condition=Good"
},
"importContract": {
"method": "POST",
"path": "/api/v1/layers/{layerId}/import",
"contentType": "multipart/form-data",
"formats": [
"CSV",
"GeoJSON",
"NDJSON",
"ZIP shapefile"
],
"fileField": "file",
"shapefileRule": "Upload a ZIP containing matching .shp, .dbf, and .shx files. Include .prj when coordinates require conversion to EPSG:4326.",
"fieldMap": {
"encoding": "JSON object in the multipart fieldMap form field",
"rule": "Keys are target layer fields. Values are source field names; null skips the target field.",
"example": {
"asset_id": "ASSETID",
"condition": "STATUS",
"inspection_date": "INSPECT_DT"
}
},
"csvCoordinates": {
"longitudeField": "Optional custom source longitude column.",
"latitudeField": "Optional custom source latitude column."
},
"batchSize": 500
},
"limits": {
"normalApiResponseFeatures": 1000,
"defaultGeoJsonFeatures": 1000,
"maximumSynchronousGeoJsonFeatures": 10000,
"maximumImportBytes": 209715200,
"maximumVerticesPerGeometry": 10000,
"note": "A response that has more data exposes hasMore or truncated metadata and a next cursor. LayrQ never silently truncates."
},
"structuredError": {
"error": {
"code": "VALIDATION_ERROR",
"message": "Human-readable explanation",
"details": {},
"requestId": "request UUID for support"
}
},
"instructionsForAnAiModel": [
"Return JSON only unless the user asks for an explanation.",
"Ask which geometry family to use if it cannot be inferred safely.",
"Use exactly one of point, line, or polygon for geometry.",
"Use lowercase snake_case for the layer name and every field name.",
"Declare every property the user wants to store.",
"Use enum only when the allowed values are known and finite.",
"Mark only truly mandatory fields as required.",
"Choose public, private, or unlisted deliberately; prefer private for sensitive data.",
"Do not include features, API keys, prose, Markdown, GeometryCollection, or mixed geometry in a layer specification.",
"Validate the final object against layerSpecificationSchema before returning it."
]
}