Integration API Guide

Created by Amir Karbasi, Modified on Fri, Jul 31 at 1:10 PM by Amir Karbasi

TABLE OF CONTENTS


1 Authentication

All integration API calls must be accompanied by a signed JWT. The public key must be provided to the ATLAS team prior to making any calls. Once configured, please ensure that the appropriate claims are included in the JWT - these are provided to you by the ATLAS team.

Send the token as a bearer token on every request:

Authorization: Bearer <jwt>

Requirements:

  • The token must be signed with RS256.
  • The token must include an expiry (exp). Tokens without one are rejected.
  • The account the token resolves to must be a service account. Service accounts are provisioned by the ATLAS team.

1.1 Claims

Claim names are configurable per JWT configuration; the defaults are shown below. The ATLAS team will confirm the exact claim names to use.

PurposeDefault claim nameRequiredNotes
IssuerissYesIdentifies which JWT configuration (and public key) is used
AudienceaudYesMust match the configured audience
ExpiryexpYesTokens without an expiry are rejected
OrganizationorgYesThe organization name as configured in ATLAS, not its id
UseremailYesMatched case-insensitively against users in that organization

Example claim set:

{
  "iss": "https://idp.rocketclub.ai/",
  "aud": "atlas-api",
  "exp": 1780000000,
  "org": "Rocket Club AI",
  "email": "s.service@rocketclub.ai"
}

2 General API Navigation

All top-level list integration endpoints will have the following configuration for pagination and filtering.

2.1 Filtering data

Query parameters are used to filter the results when retrieving a list of records. Please refer to the specific endpoint's documentation for available query parameter names and their respective filter types. In general, multiple filters can be combined in a single query string, for example:

GET /api/integrations/v1/leases/?name=Main&state=TX&verified=true&commencement_date_after=2023-01-01

Only the query parameters listed for each endpoint are supported. Unrecognised parameters are ignored rather than rejected, so a misspelled filter silently returns unfiltered results - check your parameter names against the tables below. There is no general-purpose search parameter, and result ordering is fixed per endpoint (there is no ordering parameter).

2.2 Pagination

This API uses page number pagination to manage large result sets. Results are divided into pages, and clients can navigate through them using the page query parameter.

  • page: The page number of results to retrieve. Example: ?page=2

  • page_size (optional): The number of results per page. If not specified, a default page size of 10,000 is used. There is no enforced maximum. Example: ?page=2&page_size=100

2.2.1 Example

To retrieve the third page of results with 100 items per page:

?page=3&page_size=100

2.2.2 Response Format

Paginated responses include metadata to assist with navigation through the result set:

{
  "count": 123,           // Total number of items available
  "next": "URL",          // Link to the next page (null if none)
  "previous": "URL",      // Link to the previous page (null if none)
  "results": [ ... ]      // Array of result objects for this page
}
  • The next and previous URLs can be used to navigate between pages.
  • The page and page_size parameters control which page and how many results are returned.

One endpoint is not paginated and returns a bare JSON array with no envelope: Lease Payment Schedules.

2.3 Date and time formats

  • Date-only fields (commencement_date, expiration_date, start_date, end_date) serialize as YYYY-MM-DD.
  • Timestamp fields (abstracted_at, verified_date, verified_at, created_at, updated_at) serialize as full ISO-8601 timestamps in UTC, e.g. 2024-06-15T14:30:00Z.
  • Date filter parameters accept YYYY-MM-DD.

Note that abstracted answers of type Date carry their value as a string in response, not as a JSON date - see Attribute question fields.

3 Error Format

Errors from this API are returned in a single consistent shape. The response body contains an errors string and, in most cases, a machine-readable code:

{ "errors": "Master template with id 999 does not exist or does not belong to your organization.", "code": "invalid" }

Authentication and permission errors:

{ "errors": "Authentication credentials were not provided.", "code": "not_authenticated" }
{ "errors": "You do not have permission to perform this action.", "code": "permission_denied" }

Not found. Note that these messages name the record type and, unlike the errors above, carry no code - rely on the 404 status rather than the body:

{ "errors": "No Lease matches the given query." }

Method not supported:

{ "errors": "Method \"DELETE\" not allowed.", "code": "method_not_allowed" }

Important characteristics of this format:

  • errors is always a string, never an object or array. When more than one field fails validation, the individual messages are joined into that single string. This means the offending field name is generally not recoverable from the response - the exception is a missing required field, which is rendered as "<field_name>: This field is required.".
  • code is a stable, lowercase identifier (invalid, not_authenticated, permission_denied, method_not_allowed, ...). Branch on code and the HTTP status rather than on the text of errors.
  • code is not always present. 404 responses and unexpected server errors omit it. Always fall back to the HTTP status.
  • An unexpected server-side failure returns 500 with {"errors": "<message>"} and no code.

A worked example of the flattening, from a POST /leases/ with an empty body - four separate field errors collapsed into one string:

{
  "errors": "external_id: This field is required. name: This field is required. template_id: This field is required. files: This field is required.",
  "code": "invalid"
}

4 Lease Management API

The lease integration API allows service accounts to list, retrieve, and create leases in ATLAS.

4.1 Endpoints

MethodURLDescription
GET/api/integrations/v1/leases/List leases
GET/api/integrations/v1/leases/{id}/Retrieve a lease
PATCH/api/integrations/v1/leases/{id}/Partially update a lease
PUT/api/integrations/v1/leases/{id}/Update a lease
POST/api/integrations/v1/leases/Create a lease
GET/api/integrations/v1/leases/{id}/payment-schedules/List a lease's payment schedules

4.2 List Leases

GET /api/integrations/v1/leases/

Returns all non-deleted leases in the authenticated service account's organization. Supports pagination and filtering. Results are always ordered by id ascending.

4.2.1 Query Parameters

ParameterTypeDescription
namestringFilter by lease name (case-insensitive, partial match)
citystringFilter by city (case-insensitive, partial match)
countystringFilter by county (case-insensitive, partial match)
statestringFilter by state (case-insensitive, partial match)
countrystringFilter by country (case-insensitive, partial match)
commencement_date_afterdateCommencement date on or after this value (YYYY-MM-DD)
commencement_date_beforedateCommencement date on or before this value (YYYY-MM-DD)
expiration_date_afterdateExpiration date on or after this value (YYYY-MM-DD)
expiration_date_beforedateExpiration date on or before this value (YYYY-MM-DD)
abstracted_at_afterdateAbstracted at on or after this value (YYYY-MM-DD)
abstracted_at_beforedateAbstracted at on or before this value (YYYY-MM-DD)
verified_date_afterdateVerified date on or after this value (YYYY-MM-DD)
verified_date_beforedateVerified date on or before this value (YYYY-MM-DD)
landlordstringFilter by landlord (case-insensitive, partial match)
tenantstringFilter by tenant (case-insensitive, partial match)
verifiedbooleanFilter by verification status (true or false)
external_idstringFilter by exact external ID
pageintegerPage number
page_sizeintegerResults per page

4.2.2 Response 200 OK

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 42,
      "status": "active",
      "name": "Office Lease - 123 Main St",
      "address": "123 Main St",
      "city": "New York",
      "county": "New York",
      "state": "NY",
      "country": "US",
      "commencement_date": "2024-01-01",
      "expiration_date": "2029-12-31",
      "landlord": "Acme Properties LLC",
      "tenant": "Globex Corp",
      "external_id": "EXT-001",
      "requires_abstraction": false,
      "percent_verified": 85,
      "verified": false,
      "verified_date": null,
      "abstracted_at": "2024-06-15T14:30:00Z",
      "version": 1,
      "files": [
        {
          "id": 10,
          "name": "lease_agreement.pdf",
          "priority_order": 0,
          "document_type": "lease"
        },
        {
          "id": 11,
          "name": "amendment_1.pdf",
          "priority_order": 1,
          "document_type": "amendment"
        }
      ],
      "task_progress": {
        "step": "not_running"
      },
      "templates": [
        {
          "id": 5,
          "name": "Gold",
          "lease_type": "Gold",
          "template_type": "master"
        }
      ],
      "created_at": "2024-06-15T10:00:00Z",
      "updated_at": "2024-06-15T14:30:00Z",
      "created_by": {
        "id": 1,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane@example.com",
        "colour": "#4A90D9"
      },
      "updated_by": {
        "id": 1,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane@example.com",
        "colour": "#4A90D9"
      }
    }
  ]
}

4.2.3 Response fields

FieldTypeDescription
idintegerLease ID
statusstringLease status - one of draft, active, revision, retired, processing, error (see below)
namestringLease name
addressstringStreet address
citystringCity
countystringCounty
statestringState or province
countrystringCountry
commencement_datedateLease start date
expiration_datedateLease end date
landlordstringLandlord name
tenantstringTenant name
external_idstringExternal system identifier. Free text, not unique, not validated
requires_abstractionbooleanWhether the lease still requires abstraction
percent_verifiedintegerPercentage of answers verified, 0-100 (whole numbers only)
verifiedbooleanWhether the lease is fully verified
verified_datedatetimeWhen the lease was fully verified, or null
abstracted_atdatetimeWhen abstraction completed, or null
versionintegerLease version number
filesarrayAttached files (see file object below)
task_progressobjectCurrent pipeline task progress, or null (see below)
templatesarrayAssociated master templates (see template object below)
created_atdatetimeWhen the lease was created
updated_atdatetimeWhen the lease was last updated
created_byobjectUser who created the lease (see profile object below)
updated_byobjectUser who last updated the lease (see profile object below)

Lease status values

ValueMeaning
draftCreated but not yet in use
activeAbstracted and in use. This is the normal steady state for a completed lease
revisionA revision is in progress
processingThe abstraction pipeline is currently running
retiredArchived and no longer active
errorThe abstraction pipeline failed

File object

FieldTypeDescription
idintegerFile ID
namestringFile name
priority_orderintegerPosition in the file list (0-indexed)
document_typestringOne of lease, amendment

Template object

FieldTypeDescription
idintegerTemplate ID. Use this value as template_id when creating a lease
namestringTemplate name
lease_typestringLease type. Free-form text configured per organization, not a fixed set of values
template_typestringAlways master for this endpoint

See Abstraction Templates to list the templates available in your organization and inspect their questions.

Profile object

FieldTypeDescription
idintegerProfile ID
first_namestringFirst name
last_namestringLast name
emailstringEmail address
colourstringAssigned display color

task_progress object

task_progress reports the live state of the background pipeline task. It is task telemetry, not a stable API contract - treat every field as advisory:

  • When no task has ever been queued for the lease, it is exactly {"step": "not_running"}.
  • When a task is queued but has not yet started, it may be null.
  • While a task is running, step is one of ingesting_files, abstracting_lease, reabstracting_lease, or abstracting_question_{question_id}_for_lease_{lease_id}. Some steps also include current, total, and percent keys; others include only step.
  • If the task failed, this object holds a representation of the error instead.

Do not branch on task_progress to detect completion. Poll status, requires_abstraction, and abstracted_at instead.


4.3 Retrieve Lease

GET /api/integrations/v1/leases/{id}/

Returns a single lease with all fields from the list endpoint plus an attributes object containing the abstracted lease data organized by category and question.

All top level lease values and abstracted attributes are provided in this endpoint. When retrieving lease attributes, the abstracted values will be found under attributes['Category Name']['Question Name']. For example, to determine the value for "# of days for Delinquency", the path would be attributes['Late Payment']['# of days for Delinquency']['response'].

Value from the UI: 

Value from the API:

{
  "attributes": {
    ...
    "Late Payment": {
      "# of days for Delinquency": {
        "response": "Payment is considered delinquent if not received within 10 days of due date.",
        "type": "Short Text",
        "verified": true,
        "verified_at": "2025-06-12T13:04:32.847796Z",
        "verified_by": "lease.admin@rocketclub.ai",
        "references": [
          {
            "file_name": "lasvegasexh1014.pdf",
            "page_num": 9,
            "reference_text": "16. COLLECTION CHARGES; ATTORNEYS' FEES: LESSEE AGREES THAT\nTIME IS OF THE ESSENCE TO THIS LEASE. Accordingly, if any part of sum is\nnot paid when due, LESSEE agrees to pay LESSOR upon demand; in the event any\nMonthly Lease Payment is not received within ten (10) days of the due date, a later\ncharge on the Monthly Lease Payment equal to five (5%); and other amounts allowed\nby law. In addition, in the event of any act of default under this Lease Agreement by\nLESSEE, LESSEE agrees to be responsible for and reimburse LESSOR for any\nreasonable attorneys' fees, courts costs and related expenses incurred by LESSOR in\nthe enforcement of its rights under this Lease Agreement."
          }
        ]
      }
    }
  ...
  }
}

4.3.1 Response 200 OK

The response includes every field from the List Leases response, plus:

FieldTypeDescription
attributesobjectAbstracted answers grouped by category and question (see below)

4.3.2 Attributes structure

The attributes object is keyed by category name, with each category containing questions keyed by question name:

{
  "attributes": {
    "Basic Information": {
      "Lease Commencement Date": {
        "response": "2024-01-01",
        "type": "Date",
        "verified": true,
        "verified_at": "2024-01-15T10:30:00Z",
        "verified_by": "user@example.com",
        "references": [
          {
            "file_name": "lease_agreement.pdf",
            "page_num": 1,
            "reference_text": "This lease shall commence on January 1, 2024"
          }
        ]
      },
      "Monthly Rent": {
        "response": "5000.00",
        "type": "Numeric",
        "verified": false,
        "verified_at": null,
        "verified_by": null,
        "references": []
      },
      "Renewal Option": {
        "response": "Yes",
        "type": "YesNo",
        "verified": false,
        "verified_at": null,
        "verified_by": null,
        "references": []
      }
    },
    "Property Details": {
      "Square Footage": {
        "response": "2500",
        "type": "Numeric",
        "verified": true,
        "verified_at": "2024-01-15T11:00:00Z",
        "verified_by": "user@example.com",
        "references": [
          {
            "file_name": "floor_plan.pdf",
            "page_num": 2,
            "reference_text": "Total rentable area: 2,500 square feet"
          }
        ]
      }
    }
  }
}

4.3.3 Attribute question fields

FieldTypeDescription
responsestringThe answer value. Always a string, whatever the type
typestringAnswer type - see the values below
verifiedbooleanWhether this answer has been verified
verified_atdatetimeWhen the answer was verified, or null
verified_bystringEmail of the verifier, or null
referencesarraySupporting references from lease documents

Answer type values

Valueresponse format
Short TextFree text, single line
Long TextFree text, potentially multi-line
NumericA number rendered as a string, e.g. "5000.00"
DateYYYY-MM-DD
YesNo"Yes" or "No"
ListA value drawn from a configured list of allowed values

Answer types are configured per deployment rather than being a fixed enum, so match these values case-insensitively and tolerate a value you do not recognise instead of failing. The six values above are the currently configured set.

4.3.4 Reference fields

FieldTypeDescription
file_namestringName of the referenced file
page_numintegerPage number in the referenced file
reference_textstringExtracted text that supports the answer

4.3.5 Response 404 Not Found

Returned when the lease does not exist, has been deleted, or belongs to another organization.

{ "errors": "No Lease matches the given query." }

4.4 Update Lease

PATCH /api/integrations/v1/leases/{id}/

Updates a single lease record's name and/or external_id fields. Any additional attributes provided will be ignored by the API.

4.4.1 Request fields

FieldTypeRequiredDescription
namestringPUT onlyLease name
external_idstringnoExternal system identifier

Sample request:

{
  "external_id": "API Update",
  "name": "Updated by the API"
}

external_id is not validated for uniqueness - reusing a value another lease already has is permitted.

4.4.2 Response 200 OK

The lease has been successfully updated. Only id, name, and external_id are returned - not the full lease object. Re-read the lease with Retrieve Lease if you need the other fields.

{
  "id": 42,
  "name": "Updated by the API",
  "external_id": "API Update"
}

4.5 Create Lease

POST /api/integrations/v1/leases/
Content-Type: multipart/form-data

Creates a new lease, uploads the associated files, and triggers the abstraction pipeline. The first file in the array is treated as the primary lease document; subsequent files are treated as amendments.

NOTE: Before the lease is created, the API validates that the organization has a valid pipeline configuration (retrieval instructions, LLM configs for retrieval, embedding, ranking, and document parsing). If the configuration is incomplete, a 400 error is returned.

4.5.1 Request

Send as multipart/form-data:

FieldTypeRequiredDescription
namestringyesLease name (max 1000 characters)
external_idstringyesExternal system identifier (max 1000 characters)
template_idintegeryesID of a master template in the caller's organization. List available templates with Abstraction Templates
filesarray of filesyesPDF files to upload (non-empty). Order of array determines the file type (first would be lease and rest are amendment)

4.5.2 Response 201 Created

Returns the newly created lease object (same shape as the List Leases response). The status will be processing and task_progress will reflect the running pipeline.

{
  "id": 43,
  "status": "processing",
  "name": "New Office Lease",
  "address": null,
  "city": null,
  "county": null,
  "state": null,
  "country": null,
  "commencement_date": null,
  "expiration_date": null,
  "landlord": null,
  "tenant": null,
  "external_id": "EXT-002",
  "requires_abstraction": true,
  "percent_verified": 0,
  "verified": false,
  "verified_date": null,
  "abstracted_at": null,
  "version": 1,
  "files": [
    {
      "id": 12,
      "name": "new_lease.pdf",
      "priority_order": 0,
      "document_type": "lease"
    }
  ],
  "task_progress": null,
  "templates": [
    {
      "id": 5,
      "name": "Gold",
      "lease_type": "Gold",
      "template_type": "master"
    }
  ],
  "created_at": "2024-07-01T09:00:00Z",
  "updated_at": "2024-07-01T09:00:00Z",
  "created_by": {
    "id": 1,
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "colour": "#4A90D9"
  },
  "updated_by": {
    "id": 1,
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@example.com",
    "colour": "#4A90D9"
  }
}

Abstraction runs asynchronously - the lease returns immediately with status: "processing" and is populated over the following minutes. Poll Retrieve Lease until status leaves processing. Because the pipeline task is queued as the response is built, task_progress is commonly null on this response even though the task was accepted.

4.5.3 Response 400 Bad Request

Returned when the organization's pipeline configuration is incomplete. Note this response never carries a code:

{
  "errors": "Missing master instruction for type 'retrieval', Missing LLM configuration for type 'embedding'"
}

Or when request validation fails:

{
  "errors": "Master template with id 999 does not exist or does not belong to your organization.",
  "code": "invalid"
}
{
  "errors": "files: This field is required.",
  "code": "invalid"
}

4.6 Lease Payment Schedules

GET /api/integrations/v1/leases/{id}/payment-schedules/

Returns the abstracted payment schedules for a lease - the recurring and one-off payment obligations extracted from the lease documents.

Two behaviours differ from the rest of the API and are worth noting before you integrate:

  • The response is a bare JSON array, not a paginated envelope. There is no count/next/previous, and page/page_size have no effect.
  • Only verified schedules are returned. Schedules that have been abstracted but not yet verified in ATLAS are excluded, so a lease that has been fully abstracted can still return []. An empty array means "nothing verified", not necessarily "no payment data".

Results are ordered by start_date, then id.

4.6.1 Response 200 OK

[
  {
    "id": 101,
    "type": "Base Rent",
    "description": "Base rent for the initial term",
    "start_date": "2024-01-01",
    "end_date": "2026-12-31",
    "frequency": "monthly",
    "payment_per_period": "5000.00",
    "status": "complete",
    "verified": true,
    "verified_at": "2024-06-20T09:15:00Z",
    "custom": false,
    "abstracted_at": "2024-06-15T14:30:00Z",
    "created_at": "2024-06-15T14:30:00Z",
    "updated_at": "2024-06-20T09:15:00Z"
  },
  {
    "id": 102,
    "type": "Security Deposit",
    "description": null,
    "start_date": "2024-01-01",
    "end_date": null,
    "frequency": "one_time",
    "payment_per_period": "10000.00",
    "status": "complete",
    "verified": true,
    "verified_at": "2024-06-20T09:16:00Z",
    "custom": true,
    "abstracted_at": null,
    "created_at": "2024-06-20T09:10:00Z",
    "updated_at": "2024-06-20T09:16:00Z"
  }
]

4.6.2 Response fields

All fields are read-only.

FieldTypeDescription
idintegerPayment schedule ID
typestringPayment type name, not an ID. See Payment Types
descriptionstringFree-text description, or null
start_datedateFirst period covered, or null
end_datedateLast period covered, or null (open-ended or one-off)
frequencystringOne of one_time, monthly, yearly, or null
payment_per_periodstringDecimal amount per period as a string, e.g. "5000.00", or null
statusstringOne of draft, active, processing, complete, error. Independent of verified - a verified schedule may still be draft
verifiedbooleanAlways true on this endpoint - unverified schedules are not returned
verified_atdatetimeWhen the schedule was verified, or null. May be null even though verified is true, for schedules verified before this field was recorded
custombooleantrue if created manually in ATLAS rather than AI-abstracted
abstracted_atdatetimeWhen the schedule was abstracted, or null if it was created manually
created_atdatetimeWhen the record was created
updated_atdatetimeWhen the record was last updated

payment_per_period is a decimal string with two decimal places, up to 14 significant digits. Parse it as a decimal, not a float, to avoid rounding drift on monetary values.

4.6.3 Response 404 Not Found

Returned when the lease does not exist, has been deleted, or belongs to another organization.

{ "errors": "No Lease matches the given query." }

5 Abstraction Templates

An abstraction template defines what ATLAS extracts from a lease: a set of question categories, each containing questions, each with an answer type.

This API serves two purposes:

  1. Discovering template_id for Create Lease.
  2. Interpreting a lease's attributes. The category and question names returned here are exactly the keys used in the attributes object from Retrieve Lease, and each question's answer_type is the same value that appears as that attribute's type. Retrieving the template gives you the schema of the lease payload, including its display order.

5.1 Endpoints

MethodURLDescription
GET/api/integrations/v1/abstraction-templates/List master templates
GET/api/integrations/v1/abstraction-templates/{id}/Retrieve a template with its questions

5.2 List Abstraction Templates

GET /api/integrations/v1/abstraction-templates/

5.2.1 Query Parameters

ParameterTypeDescription
namestringFilter by template name (case-insensitive, partial match)
statusstringFilter by status (case-insensitive, partial match)
lease_typestringFilter by lease type (case-insensitive, partial match)
pageintegerPage number
page_sizeintegerResults per page

5.2.2 Response 200 OK

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 5,
      "name": "Gold",
      "description": "Standard commercial abstraction set",
      "status": "active",
      "version": 3,
      "lease_type": "Gold",
      "template_type": "master",
      "organization_id": 1,
      "created_at": "2024-01-02T08:00:00Z",
      "updated_at": "2024-05-11T16:20:00Z",
      "created_by": {
        "id": 1,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane@example.com",
        "colour": "#4A90D9"
      },
      "updated_by": {
        "id": 1,
        "first_name": "Jane",
        "last_name": "Doe",
        "email": "jane@example.com",
        "colour": "#4A90D9"
      }
    }
  ]
}

5.2.3 Response fields

FieldTypeDescription
idintegerTemplate ID. Pass as template_id when creating a lease
namestringTemplate name
descriptionstringDescription, or null
statusstringOne of draft, active, history
versionintegerTemplate version number
lease_typestringFree-form lease type label, unique per organization for master templates
template_typestringAlways master on this endpoint
organization_idintegerOwning organization ID
created_atdatetimeWhen the template was created
updated_atdatetimeWhen the template was last updated
created_byobjectProfile object (see Profile object)
updated_byobjectProfile object

5.3 Retrieve Abstraction Template

GET /api/integrations/v1/abstraction-templates/{id}/

Returns a single template with its full question tree.

5.3.1 Response 200 OK

{
  "id": 5,
  "name": "Gold",
  "description": "Standard commercial abstraction set",
  "status": "active",
  "version": 3,
  "lease_type": "Gold",
  "created_at": "2024-01-02T08:00:00Z",
  "updated_at": "2024-05-11T16:20:00Z",
  "question_categories": [
    {
      "id": 20,
      "name": "Basic Information",
      "description": "Core lease identifiers and dates",
      "sort_order": 0,
      "created_at": "2024-01-02T08:00:00Z",
      "updated_at": "2024-01-02T08:00:00Z",
      "questions": [
        {
          "id": 300,
          "name": "Lease Commencement Date",
          "description": "The date the lease term begins",
          "sort_order": 0,
          "answer_type": "Date",
          "status": "active",
          "conditional": false,
          "skip_ai": false,
          "created_at": "2024-01-02T08:00:00Z",
          "updated_at": "2024-01-02T08:00:00Z"
        },
        {
          "id": 301,
          "name": "Monthly Rent",
          "description": "Base monthly rent amount",
          "sort_order": 1,
          "answer_type": "Numeric",
          "status": "active",
          "conditional": false,
          "skip_ai": false,
          "created_at": "2024-01-02T08:00:00Z",
          "updated_at": "2024-01-02T08:00:00Z"
        }
      ]
    }
  ]
}

5.3.2 Response fields

Template-level fields are as described for the list endpoint, minus the four omitted above, plus:

FieldTypeDescription
question_categoriesarrayQuestion categories, in display order

Question category object

FieldTypeDescription
idintegerCategory ID
namestringCategory name. This is the first-level key in a lease's attributes
descriptionstringCategory description
sort_orderintegerDisplay order within the template
created_atdatetimeWhen the category was created
updated_atdatetimeWhen the category was last updated
questionsarrayQuestions in this category, in display order

Question object

FieldTypeDescription
idintegerQuestion ID
namestringQuestion name. This is the second-level key in a lease's attributes
descriptionstringQuestion description, or null
sort_orderintegerDisplay order within the category
answer_typestringAnswer type name - the same value as attributes[…][…]["type"]. See Answer type values
statusstringOne of draft, active, revision
conditionalbooleanWhether the question is only asked when a preceding condition is met
skip_aibooleanWhether the question is filled in manually rather than by the AI pipeline
created_atdatetimeWhen the question was created
updated_atdatetimeWhen the question was last updated

Both question_categories and questions are returned in display order (sort_order, then name), so this response can be used directly to lay out a lease's attributes.

5.3.3 Response 404 Not Found

Returned when the template does not exist, is not a master template, has been deleted, or belongs to another organization.

{ "errors": "No AbstractionTemplate matches the given query." }

6 Payment Types

Payment types are the organization-level categories that payment schedules are classified into, for example "Base Rent" or "CAM". The type string on a payment schedule is the name of one of these records.

6.1 Endpoints

MethodURLDescription
GET/api/integrations/v1/payment-types/List payment types
GET/api/integrations/v1/payment-types/{id}/Retrieve a payment type

Read-only. Returns the caller's organization's payment types, ordered by name.

6.2 List Payment Types

GET /api/integrations/v1/payment-types/

6.2.1 Query Parameters

This endpoint has no filters. Only pagination is supported.

ParameterTypeDescription
pageintegerPage number
page_sizeintegerResults per page

6.2.2 Response 200 OK

{
  "count": 2,
  "next": null,
  "previous": null,
  "results": [
    { "id": 7, "name": "Base Rent", "description": "Recurring base rent obligation" },
    { "id": 8, "name": "CAM", "description": "Common area maintenance charges" }
  ]
}

6.2.3 Response fields

All fields are read-only.

FieldTypeDescription
idintegerPayment type ID
namestringPayment type name. Unique within the organization. Matches the type string on payment schedules
descriptionstringDescription, or null

7 User Management API

The user management API allows service accounts to create, update and delete users from ATLAS.

7.1 Endpoints

MethodURLDescription
GET/api/integrations/v1/users/List users
POST/api/integrations/v1/users/Bulk create users
PATCH/api/integrations/v1/users/bulk-update/Bulk update users
POST/api/integrations/v1/users/bulk-delete/Bulk soft-delete users
GET/api/integrations/v1/groups/List available groups
GET/api/integrations/v1/groups/{id}/Retrieve a group

7.2 List Users

GET /api/integrations/v1/users/

Returns all users in the authenticated service account's organization, ordered by id. Supports pagination and filtering.

Deactivated users are included. Use ?is_active=true to list only users who can currently log in, or ?is_active=false to find users who have been deleted or deactivated.

NOTE: is_active controls whether the user can log into ATLAS. The bulk-delete endpoint marks this as false.

7.2.1 Query Parameters

ParameterTypeDescription
emailstringFilter by email (case-insensitive, partial match)
first_namestringFilter by first name (case-insensitive, partial match)
last_namestringFilter by last name (case-insensitive, partial match)
is_activebooleanFilter by active status (true or false)
pageintegerPage number
page_sizeintegerResults per page

7.2.2 Response 200 OK

{
  "count": 1,
  "next": null,
  "previous": null,
  "results": [
    {
      "id": 5,
      "email": "jane@example.com",
      "first_name": "Jane",
      "last_name": "Doe",
      "is_active": true,
      "group": { "id": 3, "name": "Read Only Access" }
    }
  ]
}

7.2.3 Response fields

FieldTypeDescription
idintegerDjango user ID
emailstringUser email address
first_namestringFirst name
last_namestringLast name
is_activebooleanWhether the user is active
groupobjectAssigned group (id, name) or null

A user has at most one group in ATLAS. Assigning a group replaces any existing assignment.


7.3 Bulk Create Users

POST /api/integrations/v1/users/
Content-Type: application/json

Creates one or more users in a single request. The request body must be a JSON array. Password is optional and generally not recommended. Production systems should force SSO for users.

This endpoint is not transactional. Items are processed one at a time and each successful user is committed independently. A 207 Multi-Status response therefore means some users were created. Do not blindly retry the whole batch on 207 - inspect the response, and retry only the failed items.

7.3.1 Request

[
  {
    "email": "alice@example.com",
    "first_name": "Alice",
    "last_name": "Smith",
    "group_id": 2,
    "password": "SecurePass123!"
  },
  {
    "email": "bob@example.com",
    "first_name": "Bob",
    "last_name": "Jones",
    "group_id": 1
  }
]

7.3.2 Request fields

FieldTypeRequiredDescription
emailstringyesUser email. Must be unique within the organization
first_namestringyesFirst name
last_namestringyesLast name
group_idintegernoGroup ID to assign. See List Groups
passwordstringnoPassword. A random password is generated if omitted.

7.3.3 Response 201 Created (all succeeded)

[
  {
    "id": 10,
    "email": "alice@example.com",
    "first_name": "Alice",
    "last_name": "Smith",
    "is_active": true,
    "group": { "id": 2, "name": "Lease Admin" }
  },
  {
    "id": 11,
    "email": "bob@example.com",
    "first_name": "Bob",
    "last_name": "Jones",
    "is_active": true,
    "group": { "id": 1, "name": "Application Admin" }
  }
]

7.3.4 Response 207 Multi-Status (partial failure)

Returned when at least one item fails validation. Successful items return user objects; failed items return error objects identified by their zero-based index in the request array.

[
  {
    "id": 10,
    "email": "alice@example.com",
    "first_name": "Alice",
    "last_name": "Smith",
    "is_active": true,
    "group": { "id": 1, "name": "Application Admin" }
  },
  {
    "index": 1,
    "errors": {
      "email": ["This field is required."]
    }
  }
]

Note that per-item errors here is a field-keyed object, unlike the flattened top-level Error Format. Distinguish successes from failures by testing for the presence of an errors key.

7.3.5 Response 400 Bad Request

Returned if the request body is not a JSON array.

{ "detail": "Expected a list of user objects." }

7.4 Bulk Update Users

PATCH /api/integrations/v1/users/bulk-update/
Content-Type: application/json

Updates one or more existing users. Each item is matched by email. The request body must be a JSON array.

email is the lookup key only - it identifies which user to update and cannot be used to change a user's email address. Email changes must be made in the ATLAS web application.

As with bulk create, this endpoint is not transactional - each user is saved independently, so a 207 means some updates were applied.

7.4.1 Request

[
  {
    "email": "alice@example.com",
    "first_name": "Alice-Updated",
    "group_id": 2
  },
  {
    "email": "bob@example.com",
    "is_active": false
  }
]

7.4.2 Request fields

FieldTypeRequiredDescription
emailstringyesEmail of the user to update (lookup key)
first_namestringnoUpdated first name
last_namestringnoUpdated last name
group_idintegernoReplace group assignment
is_activebooleannoActivate or deactivate the user
passwordstringnoSet a new password

group_id replaces the user's group rather than adding to it, since a user holds at most one group.

Setting is_active: false deactivates the user and soft-deletes the profile - equivalent to Bulk Delete Users. Setting is_active: true on a previously deactivated user reactivates both the login and the profile.

7.4.3 Response 200 OK (all succeeded)

[
  {
    "id": 10,
    "email": "alice@example.com",
    "first_name": "Alice-Updated",
    "last_name": "Smith",
    "is_active": true,
    "group": { "id": 2, "name": "Lease Admin" }
  },
  {
    "id": 11,
    "email": "bob@example.com",
    "first_name": "Bob",
    "last_name": "Jones",
    "is_active": false,
    "group": { "id": 1, "name": "Application Admin" }
  }
]

7.4.4 Response 207 Multi-Status (partial failure)

[
  {
    "id": 10,
    "email": "alice@example.com",
    "first_name": "Alice-Updated",
    "last_name": "Smith",
    "is_active": true,
    "group": { "id": 2, "name": "Lease Admin" }
  },
  {
    "index": 1,
    "errors": {
      "email": "User with email 'unknown@example.com' not found."
    }
  }
]

An email that does not match a user in the caller's organization is reported as a per-item error, not a top-level 404.

7.4.5 Response 400 Bad Request

{ "detail": "Expected a list of user objects." }

7.5 Bulk Delete Users

POST /api/integrations/v1/users/bulk-delete/
Content-Type: application/json

Soft-deletes users and their associated profiles. Users are matched by email. A soft-deleted user has is_active: false and remains visible via List Users so historical records keep their attribution.

7.5.1 Request

{
  "emails": ["alice@example.com", "bob@example.com"]
}

7.5.2 Request fields

FieldTypeRequiredDescription
emailsarray of stringyesEmail addresses of users to delete (min 1)

7.5.3 Response 204 No Content

All users were successfully soft-deleted. No response body.

7.5.4 Response 404 Not Found

Returned when one or more emails could not be matched to an active user in the caller's organization.

{
  "detail": "Some users were not found.",
  "not_found": ["unknown@example.com"]
}

A 404 here does not mean nothing happened. Emails that did match were already soft-deleted before this response was returned. Retrying the same list is safe - the users deleted on the first attempt simply come back in not_found, since they are no longer active.


7.6 List Groups

GET /api/integrations/v1/groups/
GET /api/integrations/v1/groups/{id}/

Returns all assignable groups. Supports pagination and filtering.

7.6.1 Query Parameters

ParameterTypeDescription
namestringFilter by group name (case-insensitive, partial match)
pageintegerPage number
page_sizeintegerResults per page

7.6.2 Response 200 OK

{
  "count": 4,
  "next": null,
  "previous": null,
  "results": [
    { "id": 1, "name": "Application Admin" },
    { "id": 2, "name": "Lease Admin" },
    { "id": 3, "name": "Read Only Access" },
    { "id": 4, "name": "Lease Verifier" }
  ]
}

7.6.3 Response fields

FieldTypeDescription
idintegerGroup ID (use in group_id field)
namestringGroup name

Group IDs are stable within a deployment but are not guaranteed to be the same across deployments - resolve them by name rather than hardcoding the values above.


8 Appendix: Enum reference

Every fixed-value field in the API, in one place.

FieldValues
Lease statusdraft, active, revision, retired, processing, error
File document_typelease, amendment, renewal, other
Attribute type / question answer_typeShort Text, Long Text, Numeric, Date, YesNo, List — configured per deployment; match case-insensitively
Payment schedule frequencyone_time, monthly, yearly, or null
Payment schedule statusdraft, active, processing, complete, error
Template statusdraft, active, history
Template template_typemaster (the only value exposed by this API)
Template lease_typeFree-form text, configured per organization. Not a fixed set
Question statusdraft, active, revision
task_progress.stepnot_running, ingesting_files, abstracting_lease, reabstracting_lease, abstracting_question_{question_id}_for_lease_{lease_id} — task telemetry, not a stable contract
Error codeinvalid, not_authenticated, permission_denied, method_not_allowed, and other standard values. Absent on 404, on 500, and on the pipeline-configuration 400

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article