Your first API request

Create an access key, read project data, write an authorised point and track changes.

Last updated:

On this pagePrepare this exampleCreate a key in the interfaceCheck the identityFind the projectPage through featuresWrite the first point to an authorised projectTrack changesIntegrate with your client

Prepare this example

This workflow checks your access key, reads a project and writes an example point to an authorised training project. The base URL is your organisation's application URL. Supply SOSOMAPS_URL and ERISIM_ANAHTARI from your environment's secure configuration. These documents contain no real installation address or working secret.

Note: Response values below are examples; identifiers and values in your installation will differ.

Use curl examples in a shell, Python examples in an environment with requests, and JavaScript examples in a server-side runtime supporting fetch and environment variables. Do not place the key in browser code delivered to visitors. The example timeout is a client choice, not a server time commitment.

Create a key in the interface

  1. Sign in with an organisation account. Choose Access keys in the user menu.
  2. Select Create API key and enter a Key name.
  3. Under Projects, choose Selected projects only and select your training project.
  4. Write access can remain disabled for the initial reading steps. For the write step, use a read/write key owned by an account with the required permissions.
  5. Set an End time if needed and select Create.
  6. Store the one-time API key secret in your secure configuration and select Saved securely, hide.

Key scope does not increase account permissions. Authentication and the key lifecycle explain revocation and rotation.

Check the identity

GET /api/v1/me returns the user and safe metadata for the key in use. Bearer authentication is required in the header; a session cookie is insufficient.

curl --fail-with-body "$SOSOMAPS_URL/api/v1/me" \
  -H "Authorization: Bearer $ERISIM_ANAHTARI"
import os
import requests

yanit = requests.get(
    os.environ["SOSOMAPS_URL"].rstrip("/") + "/api/v1/me",
    headers={"Authorization": "Bearer " + os.environ["ERISIM_ANAHTARI"]},
    timeout=30,
)
yanit.raise_for_status()
print(yanit.json())
const yanit = await fetch(
  `${process.env.SOSOMAPS_URL.replace(/\/$/, '')}/api/v1/me`,
  { headers: { Authorization: `Bearer ${process.env.ERISIM_ANAHTARI}` } }
);
if (!yanit.ok) throw new Error(`HTTP ${yanit.status}`);
console.log(await yanit.json());
{
  "user": {
    "id": 42,
    "username": "ornek-kullanici",
    "full_name": "Örnek Kullanıcı",
    "org_id": 7
  },
  "anahtar": {
    "id": 9,
    "ad": "Envanter okuma",
    "kapsam": [
      "oku"
    ],
    "proje_ids": [
      123
    ],
    "bitis_at": null
  }
}

anahtar.proje_ids is the project scope selected on the key; null means general scope restricted by current user access. Having yaz in kapsam does not grant editing permission in every project.

Find the project

Select a project identifier from GET /api/v1/projects. The response is an array with no items envelope. This example uses 123; use the value from your own response in subsequent requests.

curl --fail-with-body "$SOSOMAPS_URL/api/v1/projects" \
  -H "Authorization: Bearer $ERISIM_ANAHTARI"
import os
import requests

yanit = requests.get(
    os.environ["SOSOMAPS_URL"].rstrip("/") + "/api/v1/projects",
    headers={"Authorization": "Bearer " + os.environ["ERISIM_ANAHTARI"]},
    timeout=30,
)
yanit.raise_for_status()
print(yanit.json())
const yanit = await fetch(
  `${process.env.SOSOMAPS_URL.replace(/\/$/, '')}/api/v1/projects`,
  { headers: { Authorization: `Bearer ${process.env.ERISIM_ANAHTARI}` } }
);
if (!yanit.ok) throw new Error(`HTTP ${yanit.status}`);
console.log(await yanit.json());
[
  {
    "id": 123,
    "org_id": 7,
    "name": "Örnek fiber projesi",
    "description": "Eğitim kaydı",
    "archived": false,
    "modules": [
      "saha",
      "fiber"
    ],
    "updated_at": "2026-11-10T09:00:00+00:00",
    "erisim": "kurum"
  }
]

Use GET /api/v1/projects/{pid} for project details. Its counts field contains counts and lengths by enabled type. Do not guess identifiers absent from the project list; organisation and membership scope are checked on every request.

Page through features

The first request may include bbox in minLongitude,minLatitude,maxLongitude,maxLatitude order. The example bounds describe a working area. limit is the requested records per page.

curl --fail-with-body "$SOSOMAPS_URL/api/v1/projects/123/features?bbox=31.9,38.9,32.1,39.1&limit=100" \
  -H "Authorization: Bearer $ERISIM_ANAHTARI"
import os
import requests

yanit = requests.get(
    os.environ["SOSOMAPS_URL"].rstrip("/") + "/api/v1/projects/123/features?bbox=31.9,38.9,32.1,39.1&limit=100",
    headers={"Authorization": "Bearer " + os.environ["ERISIM_ANAHTARI"]},
    timeout=30,
)
yanit.raise_for_status()
print(yanit.json())
const yanit = await fetch(
  `${process.env.SOSOMAPS_URL.replace(/\/$/, '')}/api/v1/projects/123/features?bbox=31.9,38.9,32.1,39.1&limit=100`,
  { headers: { Authorization: `Bearer ${process.env.ERISIM_ANAHTARI}` } }
);
if (!yanit.ok) throw new Error(`HTTP ${yanit.status}`);
console.log(await yanit.json());
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "DOL-123",
      "geometry": {
        "type": "Point",
        "coordinates": [
          32.0,
          39.0
        ]
      },
      "properties": {
        "name": "Örnek dolap",
        "status": "planned",
        "id": "DOL-123",
        "type": "cabinet",
        "v": 1
      }
    }
  ],
  "next": null,
  "cursor": 25
}

If next is non-null, send it as after in the next request; null means the final page. Keep filters unchanged between pages. Process features by identifier. Also save the first read's cursor; it is different from the feature pagination next value.

This Python loop reads all pages. next can be a string identifier; do not convert it to a number. When the loop ends, ilk_cursor is the starting point for change tracking.

import os
import requests

url = os.environ["SOSOMAPS_URL"].rstrip("/") + "/api/v1/projects/123/features"
baslik = {"Authorization": "Bearer " + os.environ["ERISIM_ANAHTARI"]}
params = {"bbox": "31.9,38.9,32.1,39.1", "limit": 100}
ilk_cursor = None
while True:
    yanit = requests.get(url, headers=baslik, params=params, timeout=30)
    yanit.raise_for_status()
    sayfa = yanit.json()
    if ilk_cursor is None:
        ilk_cursor = sayfa["cursor"]
    for nesne in sayfa["features"]:
        print(nesne["id"], nesne["properties"]["v"])
    if sayfa["next"] is None:
        break
    params["after"] = sayfa["next"]

Write the first point to an authorised project

This step creates a record. Check the training project, the key's oku and yaz scopes, and the account's project and region permissions. Save this body as istek.json. Choose a separate request_id for each new operation; if the response for the same work is lost, retry with the same identifier and ops.

{
  "request_id": "ornek-duzenleme-20261110-01",
  "note": "Örnek nokta kaydı",
  "ops": [
    {
      "op": "create",
      "entity": "feature",
      "id": "gecici-dolap",
      "type": "cabinet",
      "geometry": {
        "type": "Point",
        "coordinates": [
          32.0,
          39.0
        ]
      },
      "props": {
        "name": "Örnek dolap",
        "status": "planned"
      }
    }
  ]
}
curl --fail-with-body "$SOSOMAPS_URL/api/v1/projects/123/edit" \
  -H "Authorization: Bearer $ERISIM_ANAHTARI" \
  -H 'Content-Type: application/json' \
  --data-binary @istek.json
import json
import os
import requests

with open("istek.json", encoding="utf-8") as dosya:
    istek = json.load(dosya)
yanit = requests.post(
    os.environ["SOSOMAPS_URL"].rstrip("/") + "/api/v1/projects/123/edit",
    headers={"Authorization": "Bearer " + os.environ["ERISIM_ANAHTARI"]},
    json=istek, timeout=30,
)
yanit.raise_for_status()
print(yanit.json())
import { readFile } from 'node:fs/promises';
const istek = JSON.parse(await readFile('istek.json', 'utf8'));
const yanit = await fetch(
  `${process.env.SOSOMAPS_URL.replace(/\/$/, '')}/api/v1/projects/123/edit`,
  {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.ERISIM_ANAHTARI}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(istek)
  }
);
if (!yanit.ok) throw new Error(`HTTP ${yanit.status}`);
console.log(await yanit.json());

Example successful response:

{
  "ok": true,
  "batch": "ornek-islem",
  "ids": [
    "DOL-123"
  ],
  "tmp": {
    "gecici-dolap": "DOL-123"
  },
  "features": [
    {
      "type": "Feature",
      "id": "DOL-123",
      "geometry": {
        "type": "Point",
        "coordinates": [
          32.0,
          39.0
        ]
      },
      "properties": {
        "name": "Örnek dolap",
        "status": "planned",
        "id": "DOL-123",
        "type": "cabinet",
        "v": 1,
        "_deleted": false
      }
    }
  ]
}

tmp maps the request's temporary identifier to the permanent record. For the next update, send properties.v from features as version; creation has no existing record version. Do not guess or increment the version. An accepted retry of the same request may include replayed: true.

Track changes

Use the first read's cursor in GET /api/v1/projects/123/changes?after=25&limit=100. The displayed 25 is an example value. With no new changes, the response is:

{"items": [], "next": null}

When changes exist, apply items in increasing id order and persist the last successfully processed identifier. Continue paging while next is non-null. Some rows may contain gizli: true instead of before and after; this means your scope does not permit their details. Rebuild the view when scope changes.

Check the key for 401, scope and permissions for 403, and the current record version for 409. For 429, wait as specified by Retry-After. A lost write response does not prove that the operation failed. See Contract rules, Error codes and the v1 API reference.

Integrate with your client

No official SDK has been published. Import the v1 OpenAPI file into your client-generation tool or the Postman collection into your request workspace. The client-generation example in Overview provides a starting point alongside base-URL and Bearer-header configuration.