Hoppa till innehållet

Öppen beta – skarp lansering av version 1.0 den 1 januari 2027. Ställ dig i kö

API-referens

CRM

Kunder och prospekt, kontaktpersoner med roll och rättslig grund, och aktiviteter.

Lista kunder och prospekt

GET /crm/accounts listCrmAccounts

Kunder och prospekt i CRM, med personerna och deras roller.

Mer i detalj (på engelska)

The accounts in the CRM: prospects and customers, with the people at each and their role. An account that is a customer has customer_id; its ledger fields stay on the customer. Filter on status (PROSPECT, ACTIVE, INACTIVE, LOST) or customer_id. Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • limit integer fråga

    Page size, 1–200.

    Standard: 50 · minst 1 · högst 200

  • cursor string fråga

    Opaque cursor from meta.next_cursor of the previous page.

    högst 2000 tecken

  • updated_since string (date-time) fråga

    Bara poster som ändrats efter den här tiden (ISO 8601). Listor sorteras på updated_at och id.

    Exempel: 2026-03-01T00:00:00+01:00

  • status string fråga

    PROSPECT, ACTIVE, INACTIVE or LOST.

  • customer_id integer fråga

    The account of one customer.

Svar

200 OK – A page of results.

application/jsonobject

  • data array<CrmAccount> krävs
    24 fält · varje post
    • id integer
    • name string
    • kind string

      Värden: COMPANY, PERSON

    • status string

      Värden: PROSPECT, ACTIVE, INACTIVE, LOST

    • lost_reason string kan vara null
    • status_set_by_hand_at string (date-time) kan vara null

      When the status was set by hand; null while the rules decide.

    • customer_id integer kan vara null

      The customer in the customer register, once the account is a customer.

    • org_number string kan vara null
    • owner_id integer kan vara null
    • parent_id integer kan vara null

      The parent company (group), another account.

    • sni_code string kan vara null
    • website string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • address_line1 string kan vara null
    • postal_code string kan vara null
    • city string kan vara null
    • country string
    • source string kan vara null
    • tags array<string>
    • people array<object>
      2 fält · varje post
      • person_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • last_activity_at string (date-time) kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)
  • meta ListMeta krävs
    3 fält
    • limit integer krävs
    • next_cursor string krävs kan vara null

      Opaque; pass as `cursor` for the next page. null on the last page.

    • has_more boolean krävs

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/accounts?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/accounts', [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/accounts', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/crm/accounts');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/accounts",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "limit": 50,
        "updated_since": "2026-03-01T00:00:00+01:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": 41,
      "name": "Exempelbolaget AB",
      "kind": "COMPANY",
      "status": "ACTIVE",
      "lost_reason": null,
      "status_set_by_hand_at": null,
      "customer_id": 12,
      "org_number": "556036-0793",
      "owner_id": 3,
      "parent_id": null,
      "sni_code": "62010",
      "website": "exempelbolaget.example",
      "email": "info@exempelbolaget.example",
      "phone": "08-123 456 78",
      "address_line1": "Exempelgatan 1",
      "postal_code": "111 22",
      "city": "Stockholm",
      "country": "SE",
      "source": "Mässa",
      "tags": [
        "it",
        "stockholm"
      ],
      "people": [
        {
          "person_id": 7,
          "role": "DECISION_MAKER"
        }
      ],
      "last_activity_at": "2026-11-02T09:00:00+01:00",
      "created_at": "2026-11-01T10:00:00+01:00",
      "updated_at": "2026-11-02T09:00:00+01:00"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": null,
    "has_more": false
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Skapa ett prospekt

POST /crm/accounts createCrmAccount

Lägger till ett prospekt. Det får ett kundnummer först när det blir kund.

Mer i detalj (på engelska)

Adds an account as a prospect. It gets a customer number only when it becomes a customer in NONOX. The owner is the person behind the credential unless owner_id names another member. Same Action as the app (SaveAccount). Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • Idempotency-Key string huvud krävs

    Krävs på varje POST. Ett unikt värde per avsedd åtgärd (helst ett UUID). Sparas i 24 timmar per nyckel eller app, så att ett nytt försök aldrig bokför två gånger.

    minst 1 tecken · högst 255 tecken · Exempel: 3f6c1b7e-2d4a-4e8b-9c0d-5a1b2c3d4e5f

Innehåll i anropet

application/jsonCrmAccountInput krävs

  • name string krävs
  • org_number string

    Swedish organisation number, checked with Luhn.

  • kind string

    Värden: COMPANY, PERSON

  • owner_id integer

    A member of the company; the person behind the credential when left out.

  • parent_id integer
  • sni_code string
  • website string
  • email string
  • phone string
  • address_line1 string
  • postal_code string
  • city string
  • country string
  • source string
  • tags array<string>

Svar

201 Created – The account.

application/jsonobject

  • data CrmAccount krävs
    24 fält
    • id integer
    • name string
    • kind string

      Värden: COMPANY, PERSON

    • status string

      Värden: PROSPECT, ACTIVE, INACTIVE, LOST

    • lost_reason string kan vara null
    • status_set_by_hand_at string (date-time) kan vara null

      When the status was set by hand; null while the rules decide.

    • customer_id integer kan vara null

      The customer in the customer register, once the account is a customer.

    • org_number string kan vara null
    • owner_id integer kan vara null
    • parent_id integer kan vara null

      The parent company (group), another account.

    • sni_code string kan vara null
    • website string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • address_line1 string kan vara null
    • postal_code string kan vara null
    • city string kan vara null
    • country string
    • source string kan vara null
    • tags array<string>
    • people array<object>
      2 fält · varje post
      • person_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • last_activity_at string (date-time) kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Idempotent-Replayed

400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.

Alla felkoder · application/problem+json

  • idempotency_key_requiredNo Idempotency-Key on a POST

    Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.

  • idempotency_key_invalidIdempotency-Key too long or not visible ASCII

    Idempotency-Key ska vara 1–255 synliga ASCII-tecken.

  • invalid_jsonMalformed JSON

    Kroppen är inte giltig JSON (ett objekt).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

409 Conflict – A request with the same Idempotency-Key is still running.

Alla felkoder · application/problem+json

  • idempotency_in_progressSame key, first request not finished

    En begäran med samma Idempotency-Key pågår. Vänta och försök igen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X POST "https://nonox.app/api/v1/crm/accounts" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Exempelbolaget AB",
  "org_number": "556036-0793",
  "city": "Stockholm",
  "source": "Mässa",
  "tags": [
    "it"
  ]
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
    ->post('https://nonox.app/api/v1/crm/accounts', [
        'name' => 'Exempelbolaget AB',
        'org_number' => '556036-0793',
        'city' => 'Stockholm',
        'source' => 'Mässa',
        'tags' => [
            'it',
        ],
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('POST', 'https://nonox.app/api/v1/crm/accounts', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
        'Idempotency-Key' => bin2hex(random_bytes(16)),
    ],
    'json' => [
        'name' => 'Exempelbolaget AB',
        'org_number' => '556036-0793',
        'city' => 'Stockholm',
        'source' => 'Mässa',
        'tags' => [
            'it',
        ],
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/accounts', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Exempelbolaget AB",
    "org_number": "556036-0793",
    "city": "Stockholm",
    "source": "Mässa",
    "tags": [
      "it"
    ]
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import uuid
import requests

response = requests.post(
    "https://nonox.app/api/v1/crm/accounts",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Exempelbolaget AB",
        "org_number": "556036-0793",
        "city": "Stockholm",
        "source": "Mässa",
        "tags": [
            "it",
        ],
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 201

application/json
{
  "data": {
    "id": 41,
    "name": "Exempelbolaget AB",
    "kind": "COMPANY",
    "status": "PROSPECT",
    "lost_reason": null,
    "status_set_by_hand_at": null,
    "customer_id": null,
    "org_number": "556036-0793",
    "owner_id": 3,
    "parent_id": null,
    "sni_code": "62010",
    "website": "exempelbolaget.example",
    "email": "info@exempelbolaget.example",
    "phone": "08-123 456 78",
    "address_line1": "Exempelgatan 1",
    "postal_code": "111 22",
    "city": "Stockholm",
    "country": "SE",
    "source": "Mässa",
    "tags": [
      "it",
      "stockholm"
    ],
    "people": [],
    "last_activity_at": "2026-11-02T09:00:00+01:00",
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4003 exempel
No Idempotency-Key on a POST
{
  "type": "urn:nonox:problem:idempotency_key_required",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_required",
  "detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Idempotency-Key too long or not visible ASCII
{
  "type": "urn:nonox:problem:idempotency_key_invalid",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_invalid",
  "detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Malformed JSON
{
  "type": "urn:nonox:problem:invalid_json",
  "title": "Bad Request",
  "status": 400,
  "code": "invalid_json",
  "detail": "Kroppen är inte giltig JSON (ett objekt).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4091 exempel
Same key, first request not finished
{
  "type": "urn:nonox:problem:idempotency_in_progress",
  "title": "Conflict",
  "status": 409,
  "code": "idempotency_in_progress",
  "detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Hämta kund eller prospekt

GET /crm/accounts/{account} getCrmAccount

En kund eller ett prospekt, utifrån id.

Mer i detalj (på engelska)

One account by id. Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • account integer sökväg krävs

    Account id.

    Exempel: 41

Svar

200 OK – The account.

application/jsonobject

  • data CrmAccount krävs
    24 fält
    • id integer
    • name string
    • kind string

      Värden: COMPANY, PERSON

    • status string

      Värden: PROSPECT, ACTIVE, INACTIVE, LOST

    • lost_reason string kan vara null
    • status_set_by_hand_at string (date-time) kan vara null

      When the status was set by hand; null while the rules decide.

    • customer_id integer kan vara null

      The customer in the customer register, once the account is a customer.

    • org_number string kan vara null
    • owner_id integer kan vara null
    • parent_id integer kan vara null

      The parent company (group), another account.

    • sni_code string kan vara null
    • website string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • address_line1 string kan vara null
    • postal_code string kan vara null
    • city string kan vara null
    • country string
    • source string kan vara null
    • tags array<string>
    • people array<object>
      2 fält · varje post
      • person_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • last_activity_at string (date-time) kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/accounts/41" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/accounts/41');

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/accounts/41', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/accounts/41', {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/accounts/41",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 41,
    "name": "Exempelbolaget AB",
    "kind": "COMPANY",
    "status": "ACTIVE",
    "lost_reason": null,
    "status_set_by_hand_at": null,
    "customer_id": 12,
    "org_number": "556036-0793",
    "owner_id": 3,
    "parent_id": null,
    "sni_code": "62010",
    "website": "exempelbolaget.example",
    "email": "info@exempelbolaget.example",
    "phone": "08-123 456 78",
    "address_line1": "Exempelgatan 1",
    "postal_code": "111 22",
    "city": "Stockholm",
    "country": "SE",
    "source": "Mässa",
    "tags": [
      "it",
      "stockholm"
    ],
    "people": [
      {
        "person_id": 7,
        "role": "DECISION_MAKER"
      }
    ],
    "last_activity_at": "2026-11-02T09:00:00+01:00",
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Ändra kund eller prospekt

PATCH /crm/accounts/{account} updateCrmAccount

Ändrar de fält som skickas. status sätter status för hand; LOST kräver lost_reason.

Mer i detalj (på engelska)

Changes the given fields; the others keep their values. On an account that is a customer, name, numbers, e-mail, phone and address are changed in the customer register and need invoices:create of the person behind the credential. status (with lost_reason for LOST) sets the status by hand; it stands until the next invoice. Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • account integer sökväg krävs

    Account id.

    Exempel: 41

Innehåll i anropet

application/jsonCrmAccountPatch krävs

  • name string krävs
  • org_number string

    Swedish organisation number, checked with Luhn.

  • kind string

    Värden: COMPANY, PERSON

  • owner_id integer

    A member of the company; the person behind the credential when left out.

  • parent_id integer
  • sni_code string
  • website string
  • email string
  • phone string
  • address_line1 string
  • postal_code string
  • city string
  • country string
  • source string
  • tags array<string>
  • status string

    Värden: PROSPECT, ACTIVE, INACTIVE, LOST

  • lost_reason string

    Required with status LOST.

Svar

200 OK – The account.

application/jsonobject

  • data CrmAccount krävs
    24 fält
    • id integer
    • name string
    • kind string

      Värden: COMPANY, PERSON

    • status string

      Värden: PROSPECT, ACTIVE, INACTIVE, LOST

    • lost_reason string kan vara null
    • status_set_by_hand_at string (date-time) kan vara null

      When the status was set by hand; null while the rules decide.

    • customer_id integer kan vara null

      The customer in the customer register, once the account is a customer.

    • org_number string kan vara null
    • owner_id integer kan vara null
    • parent_id integer kan vara null

      The parent company (group), another account.

    • sni_code string kan vara null
    • website string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • address_line1 string kan vara null
    • postal_code string kan vara null
    • city string kan vara null
    • country string
    • source string kan vara null
    • tags array<string>
    • people array<object>
      2 fält · varje post
      • person_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • last_activity_at string (date-time) kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X PATCH "https://nonox.app/api/v1/crm/accounts/41" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "owner_id": 3,
  "status": "LOST",
  "lost_reason": "Valde en annan leverantör"
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->patch('https://nonox.app/api/v1/crm/accounts/41', [
        'owner_id' => 3,
        'status' => 'LOST',
        'lost_reason' => 'Valde en annan leverantör',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('PATCH', 'https://nonox.app/api/v1/crm/accounts/41', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'owner_id' => 3,
        'status' => 'LOST',
        'lost_reason' => 'Valde en annan leverantör',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/accounts/41', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "owner_id": 3,
    "status": "LOST",
    "lost_reason": "Valde en annan leverantör"
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.patch(
    "https://nonox.app/api/v1/crm/accounts/41",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "owner_id": 3,
        "status": "LOST",
        "lost_reason": "Valde en annan leverantör",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 41,
    "name": "Exempelbolaget AB",
    "kind": "COMPANY",
    "status": "LOST",
    "lost_reason": "Valde en annan leverantör",
    "status_set_by_hand_at": "2026-11-02T09:00:00+01:00",
    "customer_id": 12,
    "org_number": "556036-0793",
    "owner_id": 3,
    "parent_id": null,
    "sni_code": "62010",
    "website": "exempelbolaget.example",
    "email": "info@exempelbolaget.example",
    "phone": "08-123 456 78",
    "address_line1": "Exempelgatan 1",
    "postal_code": "111 22",
    "city": "Stockholm",
    "country": "SE",
    "source": "Mässa",
    "tags": [
      "it",
      "stockholm"
    ],
    "people": [
      {
        "person_id": 7,
        "role": "DECISION_MAKER"
      }
    ],
    "last_activity_at": "2026-11-02T09:00:00+01:00",
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Lista kontaktpersoner

GET /crm/people listCrmPeople

Kontaktpersonerna med företag, roll och rättslig grund.

Mer i detalj (på engelska)

The contact people with the accounts they are at, their role there, and the legal basis they are kept on (GDPR). Filter on account_id. Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • limit integer fråga

    Page size, 1–200.

    Standard: 50 · minst 1 · högst 200

  • cursor string fråga

    Opaque cursor from meta.next_cursor of the previous page.

    högst 2000 tecken

  • updated_since string (date-time) fråga

    Bara poster som ändrats efter den här tiden (ISO 8601). Listor sorteras på updated_at och id.

    Exempel: 2026-03-01T00:00:00+01:00

  • account_id integer fråga

    The people at one account.

Svar

200 OK – A page of results.

application/jsonobject

  • data array<CrmPerson> krävs
    16 fält · varje post
    • id integer
    • name string
    • title string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • mobile string kan vara null
    • legal_basis string

      Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

    • legal_basis_note string kan vara null
    • consent_at string (date) kan vara null
    • is_active boolean
    • informed_at string (date) kan vara null

      When the person was given the information in GDPR art. 14.

    • do_not_contact boolean

      The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

    • do_not_contact_reason string kan vara null

      OBJECTION or RESTRICTION.

    • accounts array<object>
      2 fält · varje post
      • account_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • created_at string (date-time)
    • updated_at string (date-time)
  • meta ListMeta krävs
    3 fält
    • limit integer krävs
    • next_cursor string krävs kan vara null

      Opaque; pass as `cursor` for the next page. null on the last page.

    • has_more boolean krävs

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/people?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/people', [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/people', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/crm/people');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/people",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "limit": 50,
        "updated_since": "2026-03-01T00:00:00+01:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": 7,
      "name": "Anna Exempel",
      "title": "Inköpschef",
      "email": "anna@exempelbolaget.example",
      "phone": null,
      "mobile": "070-123 45 67",
      "legal_basis": "LEGITIMATE_INTEREST",
      "legal_basis_note": null,
      "consent_at": null,
      "is_active": true,
      "accounts": [
        {
          "account_id": 41,
          "role": "DECISION_MAKER"
        }
      ],
      "created_at": "2026-11-01T10:00:00+01:00",
      "updated_at": "2026-11-02T09:00:00+01:00"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": null,
    "has_more": false
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Skapa en kontaktperson

POST /crm/people createCrmPerson

Lägger till en kontaktperson med rättslig grund, och kopplar den till ett företag med account_id och role.

Mer i detalj (på engelska)

Adds a contact person. legal_basis is required (AGREEMENT, LEGITIMATE_INTEREST or CONSENT, with consent_at for CONSENT). account_id and role place the person at an account at once. Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • Idempotency-Key string huvud krävs

    Krävs på varje POST. Ett unikt värde per avsedd åtgärd (helst ett UUID). Sparas i 24 timmar per nyckel eller app, så att ett nytt försök aldrig bokför två gånger.

    minst 1 tecken · högst 255 tecken · Exempel: 3f6c1b7e-2d4a-4e8b-9c0d-5a1b2c3d4e5f

Innehåll i anropet

application/jsonCrmPersonInput krävs

  • name string krävs
  • title string
  • email string
  • phone string
  • mobile string
  • legal_basis string krävs

    The legal basis for keeping the person (GDPR art. 6.1).

    Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

  • legal_basis_note string
  • consent_at string (date)

    Required with CONSENT.

  • is_active boolean
  • informed_at string (date)

    When the person was given the information in GDPR art. 14.

  • do_not_contact boolean

    The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

  • do_not_contact_reason string

    Värden: OBJECTION, RESTRICTION

  • account_id integer

    Place the new person at this account.

  • role CrmRole

    Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

Svar

201 Created – The person.

application/jsonobject

  • data CrmPerson krävs
    16 fält
    • id integer
    • name string
    • title string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • mobile string kan vara null
    • legal_basis string

      Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

    • legal_basis_note string kan vara null
    • consent_at string (date) kan vara null
    • is_active boolean
    • informed_at string (date) kan vara null

      When the person was given the information in GDPR art. 14.

    • do_not_contact boolean

      The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

    • do_not_contact_reason string kan vara null

      OBJECTION or RESTRICTION.

    • accounts array<object>
      2 fält · varje post
      • account_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Idempotent-Replayed

400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.

Alla felkoder · application/problem+json

  • idempotency_key_requiredNo Idempotency-Key on a POST

    Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.

  • idempotency_key_invalidIdempotency-Key too long or not visible ASCII

    Idempotency-Key ska vara 1–255 synliga ASCII-tecken.

  • invalid_jsonMalformed JSON

    Kroppen är inte giltig JSON (ett objekt).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

409 Conflict – A request with the same Idempotency-Key is still running.

Alla felkoder · application/problem+json

  • idempotency_in_progressSame key, first request not finished

    En begäran med samma Idempotency-Key pågår. Vänta och försök igen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X POST "https://nonox.app/api/v1/crm/people" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Anna Exempel",
  "title": "Inköpschef",
  "mobile": "070-123 45 67",
  "legal_basis": "LEGITIMATE_INTEREST",
  "account_id": 41,
  "role": "DECISION_MAKER"
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
    ->post('https://nonox.app/api/v1/crm/people', [
        'name' => 'Anna Exempel',
        'title' => 'Inköpschef',
        'mobile' => '070-123 45 67',
        'legal_basis' => 'LEGITIMATE_INTEREST',
        'account_id' => 41,
        'role' => 'DECISION_MAKER',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('POST', 'https://nonox.app/api/v1/crm/people', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
        'Idempotency-Key' => bin2hex(random_bytes(16)),
    ],
    'json' => [
        'name' => 'Anna Exempel',
        'title' => 'Inköpschef',
        'mobile' => '070-123 45 67',
        'legal_basis' => 'LEGITIMATE_INTEREST',
        'account_id' => 41,
        'role' => 'DECISION_MAKER',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/people', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "name": "Anna Exempel",
    "title": "Inköpschef",
    "mobile": "070-123 45 67",
    "legal_basis": "LEGITIMATE_INTEREST",
    "account_id": 41,
    "role": "DECISION_MAKER"
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import uuid
import requests

response = requests.post(
    "https://nonox.app/api/v1/crm/people",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "name": "Anna Exempel",
        "title": "Inköpschef",
        "mobile": "070-123 45 67",
        "legal_basis": "LEGITIMATE_INTEREST",
        "account_id": 41,
        "role": "DECISION_MAKER",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 201

application/json
{
  "data": {
    "id": 7,
    "name": "Anna Exempel",
    "title": "Inköpschef",
    "email": "anna@exempelbolaget.example",
    "phone": null,
    "mobile": "070-123 45 67",
    "legal_basis": "LEGITIMATE_INTEREST",
    "legal_basis_note": null,
    "consent_at": null,
    "is_active": true,
    "accounts": [
      {
        "account_id": 41,
        "role": "DECISION_MAKER"
      }
    ],
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4003 exempel
No Idempotency-Key on a POST
{
  "type": "urn:nonox:problem:idempotency_key_required",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_required",
  "detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Idempotency-Key too long or not visible ASCII
{
  "type": "urn:nonox:problem:idempotency_key_invalid",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_invalid",
  "detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Malformed JSON
{
  "type": "urn:nonox:problem:invalid_json",
  "title": "Bad Request",
  "status": 400,
  "code": "invalid_json",
  "detail": "Kroppen är inte giltig JSON (ett objekt).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4091 exempel
Same key, first request not finished
{
  "type": "urn:nonox:problem:idempotency_in_progress",
  "title": "Conflict",
  "status": 409,
  "code": "idempotency_in_progress",
  "detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Hämta kontaktperson

GET /crm/people/{person} getCrmPerson

En kontaktperson, utifrån id.

Mer i detalj (på engelska)

One contact person by id. Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • person integer sökväg krävs

    Person id.

    Exempel: 7

Svar

200 OK – The person.

application/jsonobject

  • data CrmPerson krävs
    16 fält
    • id integer
    • name string
    • title string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • mobile string kan vara null
    • legal_basis string

      Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

    • legal_basis_note string kan vara null
    • consent_at string (date) kan vara null
    • is_active boolean
    • informed_at string (date) kan vara null

      When the person was given the information in GDPR art. 14.

    • do_not_contact boolean

      The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

    • do_not_contact_reason string kan vara null

      OBJECTION or RESTRICTION.

    • accounts array<object>
      2 fält · varje post
      • account_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/people/7" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/people/7');

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/people/7', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/people/7', {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/people/7",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 7,
    "name": "Anna Exempel",
    "title": "Inköpschef",
    "email": "anna@exempelbolaget.example",
    "phone": null,
    "mobile": "070-123 45 67",
    "legal_basis": "LEGITIMATE_INTEREST",
    "legal_basis_note": null,
    "consent_at": null,
    "is_active": true,
    "accounts": [
      {
        "account_id": 41,
        "role": "DECISION_MAKER"
      }
    ],
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Ändra kontaktperson

PATCH /crm/people/{person} updateCrmPerson

Ändrar de fält som skickas.

Mer i detalj (på engelska)

Changes the given fields; the others keep their values. Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • person integer sökväg krävs

    Person id.

    Exempel: 7

Innehåll i anropet

application/jsonCrmPersonPatch krävs

  • name string
  • title string
  • email string
  • phone string
  • mobile string
  • legal_basis string

    Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

  • legal_basis_note string
  • consent_at string (date)
  • is_active boolean
  • informed_at string (date)

    When the person was given the information in GDPR art. 14.

  • do_not_contact boolean

    The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

  • do_not_contact_reason string

    Värden: OBJECTION, RESTRICTION

Svar

200 OK – The person.

application/jsonobject

  • data CrmPerson krävs
    16 fält
    • id integer
    • name string
    • title string kan vara null
    • email string kan vara null
    • phone string kan vara null
    • mobile string kan vara null
    • legal_basis string

      Värden: AGREEMENT, LEGITIMATE_INTEREST, CONSENT

    • legal_basis_note string kan vara null
    • consent_at string (date) kan vara null
    • is_active boolean
    • informed_at string (date) kan vara null

      When the person was given the information in GDPR art. 14.

    • do_not_contact boolean

      The person objected (art. 21) or restricted the processing (art. 18): no new calls, meetings, e-mails or tasks, only notes.

    • do_not_contact_reason string kan vara null

      OBJECTION or RESTRICTION.

    • accounts array<object>
      2 fält · varje post
      • account_id integer
      • role CrmRole

        Värden: DECISION_MAKER, AMBASSADOR, INFLUENCER, USER, INVOICE_RECIPIENT, OTHER

    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X PATCH "https://nonox.app/api/v1/crm/people/7" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "VD"
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->patch('https://nonox.app/api/v1/crm/people/7', [
        'title' => 'VD',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('PATCH', 'https://nonox.app/api/v1/crm/people/7', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'title' => 'VD',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/people/7', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "title": "VD"
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.patch(
    "https://nonox.app/api/v1/crm/people/7",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "title": "VD",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 7,
    "name": "Anna Exempel",
    "title": "VD",
    "email": "anna@exempelbolaget.example",
    "phone": null,
    "mobile": "070-123 45 67",
    "legal_basis": "LEGITIMATE_INTEREST",
    "legal_basis_note": null,
    "consent_at": null,
    "is_active": true,
    "accounts": [
      {
        "account_id": 41,
        "role": "DECISION_MAKER"
      }
    ],
    "created_at": "2026-11-01T10:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Lista aktiviteter

GET /crm/activities listCrmActivities

Anteckningar, samtal, möten, e-post och uppgifter.

Mer i detalj (på engelska)

Notes, calls, meetings, e-mails and tasks. done_at is null while an activity is open. Filter on account_id, assigned_to, or open (true for open, false for done). Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • limit integer fråga

    Page size, 1–200.

    Standard: 50 · minst 1 · högst 200

  • cursor string fråga

    Opaque cursor from meta.next_cursor of the previous page.

    högst 2000 tecken

  • updated_since string (date-time) fråga

    Bara poster som ändrats efter den här tiden (ISO 8601). Listor sorteras på updated_at och id.

    Exempel: 2026-03-01T00:00:00+01:00

  • account_id integer fråga

    The activities of one account.

  • assigned_to integer fråga

    The activities of one user.

  • open boolean fråga

    true for open, false for done.

Svar

200 OK – A page of results.

application/jsonobject

  • data array<CrmActivity> krävs
    13 fält · varje post
    • id integer
    • account_id integer
    • person_id integer kan vara null
    • type CrmActivityType

      Värden: NOTE, CALL, MEETING, EMAIL, TASK

    • call_outcome string kan vara null

      REACHED, NO_ANSWER, LEFT_MESSAGE or WRONG_NUMBER; calls only.

    • subject string
    • body string kan vara null
    • assigned_to integer kan vara null
    • due_at string (date-time) kan vara null
    • done_at string (date-time) kan vara null

      null while the activity is open.

    • created_by integer kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)
  • meta ListMeta krävs
    3 fält
    • limit integer krävs
    • next_cursor string krävs kan vara null

      Opaque; pass as `cursor` for the next page. null on the last page.

    • has_more boolean krävs

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/activities?limit=50&updated_since=2026-03-01T00%3A00%3A00%2B01%3A00" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/activities', [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/activities', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'query' => [
        'limit' => 50,
        'updated_since' => '2026-03-01T00:00:00+01:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const url = new URL('https://nonox.app/api/v1/crm/activities');
url.searchParams.set('limit', '50');
url.searchParams.set('updated_since', '2026-03-01T00:00:00+01:00');

const response = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/activities",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    params={
        "limit": 50,
        "updated_since": "2026-03-01T00:00:00+01:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": [
    {
      "id": 93,
      "account_id": 41,
      "person_id": 7,
      "type": "MEETING",
      "call_outcome": null,
      "subject": "Visning",
      "body": null,
      "assigned_to": 3,
      "due_at": "2026-11-20T10:00:00+01:00",
      "done_at": null,
      "created_by": 3,
      "created_at": "2026-11-02T09:00:00+01:00",
      "updated_at": "2026-11-02T09:00:00+01:00"
    }
  ],
  "meta": {
    "limit": 50,
    "next_cursor": null,
    "has_more": false
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Logga eller planera en aktivitet

POST /crm/activities createCrmActivity

Loggar en aktivitet eller planerar den. En anteckning är klar direkt; övriga är klara med "done": true.

Mer i detalj (på engelska)

Logs an activity on an account, or plans one. A NOTE is done when it is written; the other types are done with "done": true and otherwise open, with an optional due_at (Europe/Stockholm when no offset is given). The activity belongs to the person behind the credential unless assigned_to names another member. Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • Idempotency-Key string huvud krävs

    Krävs på varje POST. Ett unikt värde per avsedd åtgärd (helst ett UUID). Sparas i 24 timmar per nyckel eller app, så att ett nytt försök aldrig bokför två gånger.

    minst 1 tecken · högst 255 tecken · Exempel: 3f6c1b7e-2d4a-4e8b-9c0d-5a1b2c3d4e5f

Innehåll i anropet

application/jsonCrmActivityInput krävs

  • account_id integer krävs
  • person_id integer
  • type CrmActivityType krävs

    Värden: NOTE, CALL, MEETING, EMAIL, TASK

  • call_outcome string

    Värden: REACHED, NO_ANSWER, LEFT_MESSAGE, WRONG_NUMBER

  • subject string

    The name of the type when left out.

  • body string
  • assigned_to integer
  • due_at string

    Date and time; Europe/Stockholm when no offset is given.

  • done boolean

Svar

201 Created – The activity.

application/jsonobject

  • data CrmActivity krävs
    13 fält
    • id integer
    • account_id integer
    • person_id integer kan vara null
    • type CrmActivityType

      Värden: NOTE, CALL, MEETING, EMAIL, TASK

    • call_outcome string kan vara null

      REACHED, NO_ANSWER, LEFT_MESSAGE or WRONG_NUMBER; calls only.

    • subject string
    • body string kan vara null
    • assigned_to integer kan vara null
    • due_at string (date-time) kan vara null
    • done_at string (date-time) kan vara null

      null while the activity is open.

    • created_by integer kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Idempotent-Replayed

400 Bad Request – Bad request: missing or invalid Idempotency-Key, or a body that is not a JSON object.

Alla felkoder · application/problem+json

  • idempotency_key_requiredNo Idempotency-Key on a POST

    Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.

  • idempotency_key_invalidIdempotency-Key too long or not visible ASCII

    Idempotency-Key ska vara 1–255 synliga ASCII-tecken.

  • invalid_jsonMalformed JSON

    Kroppen är inte giltig JSON (ett objekt).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

409 Conflict – A request with the same Idempotency-Key is still running.

Alla felkoder · application/problem+json

  • idempotency_in_progressSame key, first request not finished

    En begäran med samma Idempotency-Key pågår. Vänta och försök igen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X POST "https://nonox.app/api/v1/crm/activities" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "account_id": 41,
  "person_id": 7,
  "type": "MEETING",
  "subject": "Visning",
  "due_at": "2026-11-20T10:00"
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->withHeaders(['Idempotency-Key' => (string) Str::uuid()])
    ->post('https://nonox.app/api/v1/crm/activities', [
        'account_id' => 41,
        'person_id' => 7,
        'type' => 'MEETING',
        'subject' => 'Visning',
        'due_at' => '2026-11-20T10:00',
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('POST', 'https://nonox.app/api/v1/crm/activities', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
        'Idempotency-Key' => bin2hex(random_bytes(16)),
    ],
    'json' => [
        'account_id' => 41,
        'person_id' => 7,
        'type' => 'MEETING',
        'subject' => 'Visning',
        'due_at' => '2026-11-20T10:00',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/activities', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "account_id": 41,
    "person_id": 7,
    "type": "MEETING",
    "subject": "Visning",
    "due_at": "2026-11-20T10:00"
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import uuid
import requests

response = requests.post(
    "https://nonox.app/api/v1/crm/activities",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "account_id": 41,
        "person_id": 7,
        "type": "MEETING",
        "subject": "Visning",
        "due_at": "2026-11-20T10:00",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 201

application/json
{
  "data": {
    "id": 93,
    "account_id": 41,
    "person_id": 7,
    "type": "MEETING",
    "call_outcome": null,
    "subject": "Visning",
    "body": null,
    "assigned_to": 3,
    "due_at": "2026-11-20T10:00:00+01:00",
    "done_at": null,
    "created_by": 3,
    "created_at": "2026-11-02T09:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4003 exempel
No Idempotency-Key on a POST
{
  "type": "urn:nonox:problem:idempotency_key_required",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_required",
  "detail": "Skicka en unik Idempotency-Key (till exempel ett UUID) med varje POST, så att ett nytt försök aldrig bokför två gånger.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Idempotency-Key too long or not visible ASCII
{
  "type": "urn:nonox:problem:idempotency_key_invalid",
  "title": "Bad Request",
  "status": 400,
  "code": "idempotency_key_invalid",
  "detail": "Idempotency-Key ska vara 1–255 synliga ASCII-tecken.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Malformed JSON
{
  "type": "urn:nonox:problem:invalid_json",
  "title": "Bad Request",
  "status": 400,
  "code": "invalid_json",
  "detail": "Kroppen är inte giltig JSON (ett objekt).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4091 exempel
Same key, first request not finished
{
  "type": "urn:nonox:problem:idempotency_in_progress",
  "title": "Conflict",
  "status": 409,
  "code": "idempotency_in_progress",
  "detail": "En begäran med samma Idempotency-Key pågår. Vänta och försök igen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Hämta aktivitet

GET /crm/activities/{activity} getCrmActivity

En aktivitet, utifrån id.

Mer i detalj (på engelska)

One activity by id. Needs crm:view, which no one has while the CRM module is off.

Behörighet

crm:view

Parametrar

  • activity integer sökväg krävs

    Activity id.

    Exempel: 93

Svar

200 OK – The activity.

application/jsonobject

  • data CrmActivity krävs
    13 fält
    • id integer
    • account_id integer
    • person_id integer kan vara null
    • type CrmActivityType

      Värden: NOTE, CALL, MEETING, EMAIL, TASK

    • call_outcome string kan vara null

      REACHED, NO_ANSWER, LEFT_MESSAGE or WRONG_NUMBER; calls only.

    • subject string
    • body string kan vara null
    • assigned_to integer kan vara null
    • due_at string (date-time) kan vara null
    • done_at string (date-time) kan vara null

      null while the activity is open.

    • created_by integer kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl "https://nonox.app/api/v1/crm/activities/93" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json"
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->get('https://nonox.app/api/v1/crm/activities/93');

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('GET', 'https://nonox.app/api/v1/crm/activities/93', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/activities/93', {
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
  },
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.get(
    "https://nonox.app/api/v1/crm/activities/93",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 93,
    "account_id": 41,
    "person_id": 7,
    "type": "MEETING",
    "call_outcome": null,
    "subject": "Visning",
    "body": null,
    "assigned_to": 3,
    "due_at": "2026-11-20T10:00:00+01:00",
    "done_at": null,
    "created_by": 3,
    "created_at": "2026-11-02T09:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}

Ändra eller klarmarkera aktivitet

PATCH /crm/activities/{activity} updateCrmActivity

Ändrar de fält som skickas. "done": true klarmarkerar.

Mer i detalj (på engelska)

Changes the given fields. "done": true completes an open activity (with call_outcome for a CALL); "done": false opens it again. Needs crm:manage, which no one has while the CRM module is off.

Behörighet

crm:manage

Parametrar

  • activity integer sökväg krävs

    Activity id.

    Exempel: 93

Innehåll i anropet

application/jsonCrmActivityPatch krävs

  • account_id integer
  • person_id integer
  • type CrmActivityType

    Värden: NOTE, CALL, MEETING, EMAIL, TASK

  • call_outcome string
  • subject string
  • body string
  • assigned_to integer
  • due_at string
  • done boolean

Svar

200 OK – The activity.

application/jsonobject

  • data CrmActivity krävs
    13 fält
    • id integer
    • account_id integer
    • person_id integer kan vara null
    • type CrmActivityType

      Värden: NOTE, CALL, MEETING, EMAIL, TASK

    • call_outcome string kan vara null

      REACHED, NO_ANSWER, LEFT_MESSAGE or WRONG_NUMBER; calls only.

    • subject string
    • body string kan vara null
    • assigned_to integer kan vara null
    • due_at string (date-time) kan vara null
    • done_at string (date-time) kan vara null

      null while the activity is open.

    • created_by integer kan vara null
    • created_at string (date-time)
    • updated_at string (date-time)

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

401 Unauthorized – Missing, invalid, expired or revoked token or API key. Also returned when the person behind the credential has left the company (an OAuth grant is then revoked for good).

Alla felkoder · application/problem+json

  • unauthenticatedNo valid credential

    Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, WWW-Authenticate

403 Forbidden – The credential may not do this: a scope is missing, the granting person no longer has the permission, the address is not allowed, the company is archived (read-only) or no longer allows the app.

Alla felkoder · application/problem+json

  • insufficient_scopeScope missing or permission lost

    Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.

  • forbiddenThe action refuses (for example changing a posted voucher)

    Behörighet saknas för det här.

  • ip_not_allowedOutside the IP allowlist

    Företaget tillåter inte anrop från den här adressen.

  • company_archivedWrite to an archived company

    Företaget är arkiverat och kan bara läsas.

  • app_not_allowedThe company no longer allows the app

    Företaget tillåter inte längre den här appen.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

404 Not Found – Not found. Also the answer for another company's ids (existence is never revealed) and for every call while NONOX Connect is turned off for the company.

Alla felkoder · application/problem+json

  • not_foundUnknown id, other company's id, or module off

    Det du söker finns inte.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

415 Unsupported Media Type – The body is not application/json (or multipart/form-data where a file is accepted).

Alla felkoder · application/problem+json

  • unsupported_media_typeWrong Content-Type

    Skicka JSON (application/json).

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

422 Unprocessable Content – Validation failed, or the Idempotency-Key was already used for a different request.

Alla felkoder · application/problem+json

  • validation_failedField errors

    Uppgifterna kunde inte godtas. Se errors.

  • idempotency_key_reusedSame key, different body

    Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset

429 Too Many Requests – Rate limit exceeded (per credential, per company or per address). Wait Retry-After seconds.

Alla felkoder · application/problem+json

  • rate_limitedOver the limit

    För många anrop. Försök igen om 23 sekunder.

Svarshuvuden: X-Request-Id, RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset, Retry-After

Kodexempel

curl
curl -X PATCH "https://nonox.app/api/v1/crm/activities/93" \
  -H "Authorization: Bearer $NONOX_TOKEN" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
  "done": true
}'
PHP (Laravel)
use Illuminate\Support\Facades\Http;

$response = Http::withToken(config('services.nonox.token'))
    ->acceptJson()
    ->patch('https://nonox.app/api/v1/crm/activities/93', [
        'done' => true,
    ]);

$response->throw();

$data = $response->json('data');
PHP (Guzzle)
$client = new \GuzzleHttp\Client(['timeout' => 30]);

$response = $client->request('PATCH', 'https://nonox.app/api/v1/crm/activities/93', [
    'headers' => [
        'Authorization' => 'Bearer '.getenv('NONOX_TOKEN'),
        'Accept' => 'application/json',
    ],
    'json' => [
        'done' => true,
    ],
]);

$data = json_decode((string) $response->getBody(), true, flags: JSON_THROW_ON_ERROR)['data'];
JavaScript
const response = await fetch('https://nonox.app/api/v1/crm/activities/93', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.NONOX_TOKEN}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "done": true
  }),
});

if (!response.ok) {
  const problem = await response.json();
  throw new Error(`${problem.code}: ${problem.detail}`);
}

const { data } = await response.json();
Python
import os
import requests

response = requests.patch(
    "https://nonox.app/api/v1/crm/activities/93",
    headers={
        "Authorization": f"Bearer {os.environ['NONOX_TOKEN']}",
        "Accept": "application/json",
    },
    json={
        "done": True,
    },
    timeout=30,
)
response.raise_for_status()

data = response.json()["data"]

Svar · 200

application/json
{
  "data": {
    "id": 93,
    "account_id": 41,
    "person_id": 7,
    "type": "MEETING",
    "call_outcome": null,
    "subject": "Visning",
    "body": null,
    "assigned_to": 3,
    "due_at": "2026-11-20T10:00:00+01:00",
    "done_at": "2026-11-20T11:00:00+01:00",
    "created_by": 3,
    "created_at": "2026-11-02T09:00:00+01:00",
    "updated_at": "2026-11-02T09:00:00+01:00"
  }
}

Fel

4011 exempel
No valid credential
{
  "type": "urn:nonox:problem:unauthenticated",
  "title": "Unauthorized",
  "status": 401,
  "code": "unauthenticated",
  "detail": "Nyckeln eller token saknas, är ogiltig, har gått ut eller har återkallats.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4035 exempel
Scope missing or permission lost
{
  "type": "urn:nonox:problem:insufficient_scope",
  "title": "Forbidden",
  "status": 403,
  "code": "insufficient_scope",
  "detail": "Nyckeln eller appen saknar behörigheten vouchers:post, eller så har personen som gav den inte längre den behörigheten i företaget.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "required_scopes": [
    "vouchers:post"
  ]
}
The action refuses (for example changing a posted voucher)
{
  "type": "urn:nonox:problem:forbidden",
  "title": "Forbidden",
  "status": 403,
  "code": "forbidden",
  "detail": "Behörighet saknas för det här.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Outside the IP allowlist
{
  "type": "urn:nonox:problem:ip_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "ip_not_allowed",
  "detail": "Företaget tillåter inte anrop från den här adressen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
Write to an archived company
{
  "type": "urn:nonox:problem:company_archived",
  "title": "Forbidden",
  "status": 403,
  "code": "company_archived",
  "detail": "Företaget är arkiverat och kan bara läsas.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
The company no longer allows the app
{
  "type": "urn:nonox:problem:app_not_allowed",
  "title": "Forbidden",
  "status": 403,
  "code": "app_not_allowed",
  "detail": "Företaget tillåter inte längre den här appen.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4041 exempel
Unknown id, other company's id, or module off
{
  "type": "urn:nonox:problem:not_found",
  "title": "Not Found",
  "status": 404,
  "code": "not_found",
  "detail": "Det du söker finns inte.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4151 exempel
Wrong Content-Type
{
  "type": "urn:nonox:problem:unsupported_media_type",
  "title": "Unsupported Media Type",
  "status": 415,
  "code": "unsupported_media_type",
  "detail": "Skicka JSON (application/json).",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4222 exempel
Field errors
{
  "type": "urn:nonox:problem:validation_failed",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "validation_failed",
  "detail": "Uppgifterna kunde inte godtas. Se errors.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17",
  "errors": {
    "rows": [
      "Verifikationen balanserar inte: debet och kredit skiljer sig åt."
    ],
    "voucher_date": [
      "Det finns inget räkenskapsår som omfattar 2031-01-01."
    ]
  }
}
Same key, different body
{
  "type": "urn:nonox:problem:idempotency_key_reused",
  "title": "Unprocessable Content",
  "status": 422,
  "code": "idempotency_key_reused",
  "detail": "Idempotency-Key har redan använts för en annan begäran. Använd en ny nyckel för en ny begäran.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}
4291 exempel
Over the limit
{
  "type": "urn:nonox:problem:rate_limited",
  "title": "Too Many Requests",
  "status": 429,
  "code": "rate_limited",
  "detail": "För många anrop. Försök igen om 23 sekunder.",
  "instance": "urn:nonox:request:7f3c2a9e-4b1d-4c8e-9a51-2d6f0e8b3c17"
}