AgStack Asset Registry

The AgStack Asset Registry provides global field boundary registration and identification. Submit a field polygon (WKT or GeoJSON) and receive a permanent 256-bit (16-character alphanumeric) geo ID. Supports single and bulk registration, field retrieval, centroid calculation, and spatial overlap analysis. Production API available at api-ar.agstack.org.

Documentation

Specifications

Examples

Schemas & Data

OpenAPI Specification

agstack-asset-registry-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: AgStack Asset Registry API
  version: 1.0.0
  description: |
    Welcome to the **AgStack Asset Registry** developer portal.

    ---

    ## πŸ” Authentication Guide
    
    | Service Zone | HTTP Method | Credential Type |
    | :--- | :---: | :--- |
    | **Authentication** | `GET/POST` | **Bearer Token** (where applicable) |
    | **Field Registration** | `POST` | **Bearer Token** |
    | **Field Retrieval** | `GET/POST`| **Bearer Token** (where applicable) |


    > πŸš€ **Quick Start Guide**
    > 1. Login via `/login` to get an `access_token` and `refresh_token`.
    > 2. Use `Bearer_Token` (Lock Icon) to authorize protected routes.

servers:
  - url: https://api-ar.agstack.org
    description: Production Server

tags:
  - name: Authentication
  - name: Field Registration (POST)
  - name: Field Retrieval & Queries

paths:

  # ==============================
  # SECTION 1: AUTHENTICATION
  # ==============================
  /login:
    post:
      tags: [Authentication]
      summary: πŸ” User Login
      description: Login to the Asset Registry using email and password.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                  example: "[email protected]"
                password:
                  type: string
                  format: password
                  example: "Demo@1234"
      responses:
        '200':
          description: Successful Login
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token: { type: string }
                  refresh_token: { type: string }
        '400':
          $ref: '#/components/responses/ErrorResponse'


  # ==============================
  # SECTION 2: Field Registration (POST)
  # ==============================
  /register-field-boundary:
    post:
      tags: [Field Registration (POST)]
      summary: πŸ“ Register Field Boundary (WKT)
      security: [{Bearer_Token: []}]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterFieldWKTRequest'
      responses:
        '200':
          description: Field Boundary registered successfully or already exists.
        '400':
          $ref: '#/components/responses/ErrorResponse'

  /register-field-boundaries-geojson:
    post:
      tags: [Field Registration (POST)]
      summary: πŸ“‚ Bulk Register Field Boundaries (GeoJSON File)
      description: |
        Bulk register Field Boundaries using a GeoJSON FeatureCollection. 
        Supports both multipart file upload (`.geojson`) and raw JSON body.
      security: [{Bearer_Token: []}]
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: Upload a valid .geojson file
      responses:
        '200':
          description: Bulk registration completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  message: { type: string }
                  results: { type: array, items: { type: object } }
        '400':
          $ref: '#/components/responses/ErrorResponse'

  /register-point:
    post:
      tags: [Field Registration (POST)]
      summary: 🎯 Register a Point
      security: [{Bearer_Token: []}]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [wkt]
              properties:
                wkt: { type: string, example: "POINT(75.78209 30.90706)" }
                s2_index: { type: string, example: "8,13" }
      responses:
        '200':
          description: Point registered successfully
        '400':
          $ref: '#/components/responses/ErrorResponse'

  /register-points-geojson:
    post:
      tags: [Field Registration (POST)]
      summary: πŸ“‚ Bulk Register Points (GeoJSON)
      description: |
        Bulk register points using a GeoJSON FeatureCollection. 
        Supports both multipart file upload (`.geojson`) and raw JSON body.
      security: [{Bearer_Token: []}]
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: Upload a valid .geojson file containing Point features.
          application/json:
            schema:
              $ref: '#/components/schemas/GeoJSONFeatureCollection'
      responses:
        '200':
          description: Bulk point registration completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  message: { type: string, example: "Bulk point registration completed" }
                  results:
                    type: array
                    items:
                      $ref: '#/components/schemas/BulkPointResult'
        '400':
          $ref: '#/components/responses/ErrorResponse'

  # ==============================
  # SECTION 3: Field Retrieval & Queries
  # ==============================
  /fetch-field/{geo_id}:
    get:
      tags: [Field Retrieval & Queries]
      summary: πŸ—ΊοΈ Fetch Field Data
      parameters:
        - name: geo_id
          in: path
          required: true
          schema: { type: string }
        - name: s2_index
          in: query
          required: false
          schema: { type: string }
      responses:
        '200':
          description: Field fetched successfully
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '404':
          description: Field not found

  /fetch-field-wkt/{geo_id}:
    get:
      tags: [Field Retrieval & Queries]
      summary: πŸ“ Fetch Field WKT
      parameters:
        - name: geo_id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: WKT fetched successfully
        '400':
          $ref: '#/components/responses/ErrorResponse'

  /fetch-field-centroid/{geo_id}:
    get:
      tags: [Field Retrieval & Queries]
      summary: πŸ“Œ Fetch Field Centroid
      parameters:
        - name: geo_id
          in: path
          required: true
          schema: { type: string }
      responses:
        '200':
          description: Centroid fetched successfully
        '400':
          $ref: '#/components/responses/ErrorResponse'

  /get-percentage-overlap-two-fields:
    post:
      tags: [Field Retrieval & Queries]
      summary: πŸ“Š Get Percentage Overlap
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [geo_id_field_1, geo_id_field_2]
              properties:
                geo_id_field_1: { type: string }
                geo_id_field_2: { type: string }
      responses:
        '200':
          description: Overlap percentage calculated
        '400':
          $ref: '#/components/responses/ErrorResponse'
        '404':
          description: Field not found


# ==============================
# SECTION 4: COMPONENTS
# ==============================
components:
  securitySchemes:
    Bearer_Token:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        **Required for most operations.**
        1. Login via `/login` to get token.
        2. Paste access token here.

  schemas:
    RegisterFieldWKTRequest:
      type: object
      required: [wkt]
      properties:
        wkt:
          type: string
          example: "POLYGON((75.78209 30.90706, 75.78211 30.90645, 75.78270 30.90654, 75.78262 30.90714, 75.78209 30.90706))"
        threshold:
          type: integer
          default: 95
          description: Percentage overlap threshold
        return_s2_indices:
          type: boolean
          default: false
        s2_index:
          type: string
          example: "8,13"
          description: Comma-separated list of resolution levels

    GeoJSONFeatureCollection:
      type: object
      required: [type, features]
      properties:
        type:
          type: string
          enum: [FeatureCollection]
        features:
          type: array
          items:
            type: object
            required: [geometry]
            properties:
              type: { type: string, example: "Feature" }
              geometry:
                type: object
                required: [type, coordinates]
                properties:
                  type: { type: string, enum: [Point] }
                  coordinates: 
                    type: array
                    items: { type: number }
                    example: [75.78209, 30.90706]
              properties:
                type: object
                description: Optional properties like s2_index
                properties:
                  s2_index: { type: string, example: "8,13" }

    BulkPointResult:
      type: object
      properties:
        status: { type: string, example: "created" }
        message: { type: string, example: "Point registered successfully." }
        "Geo Id": { type: string }
        "Geo JSON": { type: object }

  responses:
    ErrorResponse:
      description: Generic Error Response
      content:
        application/json:
          schema:
            type: object
            properties:
              message:
                type: string
                example: "Error description"
              error:
                type: string
                example: "Detailed exception message"