# OpenLawn API: agent quickstart

Canonical documentation: https://openlawn.ai/docs#agents
API reference: https://openlawn.ai/docs.md
OpenAPI 3.1: https://openlawn.ai/openapi.json
API documentation index: https://openlawn.ai/docs/llms.txt
Base URL: https://api.openlawn.ai/v1
Updated: 2026-09-06

## Choose the right integration

Use the REST API for server-side agents, CRM connections, bulk address submission, and background jobs. Use the browser skill at https://openlawn.ai/developers if your agent operates the signed-in website instead. These are different paths: the REST API is not an MCP server, and the browser skill does not configure an API key.

All documentation is public. Actual API requests require authentication. OpenLawn accepts U.S. property addresses; parcel coverage and imagery quality vary. It estimates lawn area, not legal lot ownership, building perimeters, pest application rates, or a final service price.

## 1. Connect with limited permissions

Have a workspace owner or admin create a key at https://openlawn.ai/settings/api. Store it in your backend secret manager as OPENLAWN_API_KEY. Never include real keys in prompts, client-side code, source control, screenshots, or logs.

For measurement submission and retrieval, request measurements:write and measurements:read. Add account:read only to inspect the key creator's available credits; properties:read for property history; webhooks:read and webhooks:write to manage notifications. Read access covers the key's workspace, not other tenants. API keys cannot create more keys, buy credits, or administer users.

## 2. Confirm the address and intended work

Resolve any ambiguity in the customer's complete street address before submission. Obtain permission for the measurement work, especially batches. A newly completed measurement uses one credit from the key creator's account, shared with app usage. Reading results and polling existing jobs do not consume measurement credits. Queue acceptance does not guarantee credits will be available when execution starts.

If the user wants an existing result, retrieve it instead of starting a new paid run. List GET /measurements or GET /properties and follow next_cursor; these list endpoints do not have an address-search parameter. Match the returned address and stable record ID in your application.

## 3. Submit once, retry safely

Illustrative residential address; running this POST can consume a credit. Use a stable, unique idempotency key for each intended measurement. The key must contain 8–128 letters, digits, underscores, or hyphens.

```sh
curl --fail-with-body https://api.openlawn.ai/v1/measurement-jobs \
  -H "Authorization: Bearer $OPENLAWN_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: crm-property-1042-v1' \
  -d '{"address":"5915 Castle Brook Avenue Southeast, Kentwood, MI 49508"}'
```

HTTP 202 means queued, not measured. Store data.id immediately as your job ID. Reuse the same idempotency key AND address when retrying an uncertain request under the same creator/workspace. A new key can create another paid job. HTTP 409 for an address conflict requires fixing your mapping; do not blindly generate a new key.

For bulk work, POST /measurement-jobs/batch accepts 1–25 jobs per request, each with its own idempotency_key. Split larger lists into bounded batches. Inspect every response item: HTTP 202 can contain accepted jobs and per-item errors. Retry only unsuccessful or uncertain items using their original keys. At most 100 jobs may be queued/running per creator; execution concurrency is bounded by the shared worker.

## 4. Observe progress without duplicate work

```sh
curl --fail-with-body https://api.openlawn.ai/v1/measurement-jobs/JOB_ID \
  -H "Authorization: Bearer $OPENLAWN_API_KEY"
```

Replace JOB_ID with data.id from submission. Poll every 5–10 seconds with jitter, or use signed webhooks. Store your job ID so a client timeout or process restart can resume polling rather than resubmitting with a new key.

- queued or running: keep waiting within your application's deadline. Do not claim completion.
- completed: retrieve data.measurement_id via the measurement endpoint.
- failed or canceled: stop polling and report the outcome. The reservation is released. A new measurement attempt is a separate action that can consume a credit.
- 429: honor Retry-After (currently 60 seconds). The limit is 120 authenticated requests per workspace per minute, shared across keys.
- Transient network/503 errors: use capped exponential backoff and jitter. Do not retry 401/403 indefinitely; resolve authentication or scope first.

DELETE /measurement-jobs/{id} cancels a non-terminal job only for its original creator. A completed result cannot be canceled through this endpoint.

## 5. Retrieve and explain the result

```sh
curl --fail-with-body https://api.openlawn.ai/v1/measurements/MEASUREMENT_ID \
  -H "Authorization: Bearer $OPENLAWN_API_KEY"
```

Report data.turf_sqft as estimated lawn square feet, alongside the address, measurement ID, and relevant uncertainty. Geometry uses normalized_image coordinates: x/y in [0,1], with (0,0) at the image's top left. They are NOT longitude/latitude or GeoJSON. Preserve the full image frame and apply additions and subtractions in the returned actions; do not simply sum overlapping polygon areas.

Read parcel_turf_sqft, verge_sqft, and inferred_maintained_sqft separately when available. Maintained extensions are not evidence of ownership or permission to service land. Confidence is a model estimate, not an independently certified accuracy score. Ask for human review before using the result in a quote.

snapshot_url is private signed access and expires after five minutes. Do not publish it or treat it as a permanent asset. Request the detail again for a fresh link. Measurement results, addresses, geometry, API keys, and webhook secrets must not be placed in public documentation or crawler indexes.

## 6. Receive signed completion events

Register an approved HTTPS receiver using POST /webhooks or the API connections screen. Save signing_secret securely at creation. Zapier and Make domains are supported; custom receiver domains require approval through support@joinclicki.com. Arbitrary destinations and redirects are not allowed.

Events include measurement.completed, measurement.failed, measurement.canceled, and webhook.test. Terminal events cover the workspace, including measurements started in the app. Webhook data contains IDs and status; fetch the full measurement with your key.

Verify OpenLawn-Signature using HMAC-SHA256 over TIMESTAMP + "." + the exact raw body. Reject timestamps outside a five-minute window and compare signatures safely. Deduplicate by event ID, durably accept before returning 2xx, and tolerate out-of-order delivery. The dispatcher checks each minute and retries up to five attempts. A test event can be queued without running AI or spending a measurement credit. See https://openlawn.ai/docs#webhooks for verification code and receiver restrictions.

## Support and next steps

- Human-readable reference: https://openlawn.ai/docs
- Complete machine-readable schemas: https://openlawn.ai/openapi.json
- Pricing: https://openlawn.ai/#pricing
- Coverage and accuracy limits: https://openlawn.ai/lawn-measurement-guide#accuracy
- Support: support@joinclicki.com (include request_id, never credentials)
