> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.useopenwrench.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Arbetsordrar i Buyer API

> Skapa, lista, filtrera, tilldela om och avsluta arbetsordrar med OpenWrench Buyer API, inklusive statusåtgärder, anteckningar, etiketter och problemtyper.

Arbetsordrar är i centrum för Buyer API. Den här guiden täcker hela ytan under `/v1/buyer/work_order/`: att skapa arbetsordrar, söka i dem, köparsidans statusåtgärder, anteckningstråden, etiketterna och problemtyperna.

Alla exempel förutsätter dessa skalvariabler:

```bash theme={null}
export BASE="https://api.useopenwrench.com/api/external"
export KEY="<your-api-key>"        # X-API-KEY header
export SECRET="<shared-secret>"    # OW-KEY header
```

## Arbetsorderobjektet

En arbetsorder som returneras av API:et bär bland annat följande fält:

| Fält                                                                 | Anmärkningar                                                                                                                                                |
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                                                 | Numeriskt id som används av alla andra slutpunkter.                                                                                                         |
| `title`, `description`                                               | Vad som ska göras. `descriptionNonFormatted` är varianten i ren text.                                                                                       |
| `status`, `displayStatus`                                            | `status` är den finkorniga maskinstatusen (se [statusmodellen](#statusmodellen)); `displayStatus` är den grövre etiketten som visas i användargränssnittet. |
| `locationId`, `assetId`, `subAssetIds`, `areaId`                     | Var arbetet utförs och vad det gäller.                                                                                                                      |
| `problemTypeId`, `workCategoryId`, `spendCategoryId`, `woPriorityId` | Klassificering.                                                                                                                                             |
| `supplierFacilityId`, `supplierPrimaryContactEmail`                  | Tilldelad leverantör, när den väl har skickats ut.                                                                                                          |
| `nte`, `price`, `currencyId`                                         | Ej-överskridande-belopp och prissättning.                                                                                                                   |
| `scheduledAt`, `estimatedCompletionDate`, `dueDate`, `completedAt`   | Viktiga datum.                                                                                                                                              |
| `notes`, `lastNote`, `lastNoteAddedBy`, `lastNoteAddedAt`            | Köpar–leverantör-anteckningstråden. `lastNoteAddedAt` är epokmillisekunder.                                                                                 |
| `associatedServiceCalls`, `lastServiceCall`                          | Besök loggade av leverantören. Se [Servicebesök](/sv/buyer-api/service-calls).                                                                              |
| `statusChanges`                                                      | Fullständig statushistorik.                                                                                                                                 |
| `buyerAttachments`, `supplierAttachments`                            | Filreferenser. Se [Filer och bilagor](/sv/buyer-api/files-and-attachments).                                                                                 |
| `isPM`, `plannedMaintenanceScheduleId`                               | Sätts när arbetsordern har genererats från ett PM-schema.                                                                                                   |
| `walkThroughId`                                                      | Sätts när arbetsordern kom från en genomgång vid en platsbesiktning.                                                                                        |

## Skapa en arbetsorder

`POST /v1/buyer/work_order/work_orders` kräver mer än de uppenbara fälten. Till skillnad från de flesta köparslutpunkter måste **`buyerFacilityId`, `buyerCompanyId` och `createdBy` anges i kroppen**; de härleds inte från din API-nyckel på den här slutpunkten. Använd [`GET /v1/buyer/me`](/sv/buyer-api/account-and-utilities) för att slå upp ditt företags- och anläggnings-id en gång och cacha dem.

Obligatoriska fält: `title`, `locationId`, `problemTypeId`, `buyerFacilityId`, `buyerCompanyId` och `createdBy` (e-postadressen till kontakten som skapar).

```bash theme={null}
curl -X POST "$BASE/v1/buyer/work_order/work_orders" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Walk-in cooler not holding temperature",
    "description": "Temp reading 48F, product at risk.",
    "locationId": 1204,
    "assetId": 5511,
    "problemTypeId": 17,
    "woPriorityId": 3,
    "nte": 500,
    "buyerFacilityId": 88,
    "buyerCompanyId": 12,
    "createdBy": "ops@example.com",
    "supplierFacilityId": 3021
  }'
```

Beteende att känna till:

* **Initial status.** Om `status` utelämnas beräknas den initiala statusen från ditt företags konfiguration. Serviceförfrågningar börjar oftast i `PendingApproval`; arbetsordrar utgår från `Unassigned`. Om du skickar en `status` löses den fortfarande mot företagets konfiguration, så den effektiva statusen kan skilja sig från vad du skickade.
* **Utskick vid skapande.** Att skicka `supplierFacilityId` tilldelar leverantören omedelbart. Ett okänt `supplierFacilityId`, `assetId` eller `problemTypeId` avvisas med `400`.
* **Underliggande tillgångar.** `subAssetIds` är en valfri array med ids för underliggande tillgångar som bifogas utöver huvud-`assetId`. Underliggande tillgångar är tillgångar skapade med ett `parentId`; se [Tillgångar](/sv/buyer-api/assets-and-locations#tillgångar).
* **Godkännandeflagga.** Fältet heter `needApproval`, inte `needsApproval`. Svarsobjektet använder `needsApproval`; själva skapa-förfrågan gör det inte.
* **Koppling till genomgång.** `walkThroughId` och `siteSurveyTaskTitleId` måste anges tillsammans eller inte alls. Se [Platsbesiktningar](/sv/buyer-api/site-survey-walkthroughs).
* **Upserts.** Att skicka ett `id` uppdaterar den befintliga arbetsordern istället för att skapa en ny.

## Lista, filtrera och räkna

```bash theme={null}
# Most recent work orders for one location
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/work_order/work_orders?locationId=1204&limit=25&sort_by=createdAt&order=desc"

# How many match, without fetching them
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/work_order/work_orders/count_by?locationId=1204"
```

List-slutpunkter tar `offset`, `limit` (standard 10, max 25), `sort_by` och `order`. Varje annan frågeparameter behandlas som ett fältfilter; kommaseparera ett värde för att matcha något av flera (`status=Unassigned,PendingApproval`). Filter kombineras alltid med tenant-avgränsningen som härleds från din nyckel, så du ser bara ditt företags arbetsordrar.

Listan och räkningen avgör vilka arbetsordrar som matchar i OpenWrenchs sökindex och laddar sedan de fullständiga posterna från databasen. Det ändrar några beteenden:

* **Fulltextsökning.** `search=` matchar ord (med prefix- och stamformsmatchning) i titeln, beskrivningen, platsnamnet, anteckningarna, servicebesökens in- och utcheckningsanteckningar och problemtypens namn. Den matchar också referensnummer som arbetsordernumret, PO-numret och tillgångens serienummer. Sätt värdet inom citattecken (`search="walk-in cooler"`) för att kräva den exakta frasen.
* **Tillgångsfilter inkluderar underliggande tillgångar.** `assetId=` och `assetIds=` matchar arbetsordrar vars huvudtillgång *eller* någon underliggande tillgång är det angivna id:t.
* **Sortering.** `sort_by` stöder `createdAt`, `locationName`, `woPriority` (efter prioritetens förväntade lösningstid) och `lastServiceCallServiceScheduledAt`. Varje annat värde, eller inget `sort_by`, sorterar fallande efter `createdAt`.
* **Oindexerade filter ignoreras.** `updatedAtStartDate`, `updatedAtEndDate`, `buyerFacilityId` och `walkthroughId` finns inte i sökindexet och smalnar inte längre av resultaten. Filtrera istället på `statusChangedAt`-fönster eller andra indexerade kolumner.
* **Färskhet.** Uppdateringar av sökindexet och läs-replikan släpar efter skrivningar ett ögonblick, så en arbetsorder som skapades för millisekunder sedan kan tillfälligt saknas i listresultat och räkningar.
* **Pagineringsdjup.** `offset + limit` kan inte överstiga sökresultatfönstret på 10 000. Smalna av filtret istället för att paginera så djupt.

Räkningsslutpunkten kör samma sökindexfråga som listan, så en räkning stämmer alltid överens med listan den beskriver.

Hämta en enskild arbetsorder med `GET /v1/buyer/work_order/work_orders/{id}`.

<Warning>
  **Använd listan för att söka, inte för att bevaka ändringar.** Om din integration behöver veta när arbetsordrar skapas, byter status eller får en ny anteckning, registrera en [webhook](/sv/buyer-api/webhooks). Hämta arbetsordern som anges i varje händelse via dess id. Att polla list-slutpunkten enligt schema är långsamt på stora konton, förbrukar din hastighetsgräns och missar ändå ändringar mellan pollningarna. Spara listanropen till ad hoc-frågor, den engångsvisa initiala laddningen och en tillfällig snävt filtrerad avstämning (`statusChangedAt`-fönster, litet `limit`).
</Warning>

## Tilldela om en leverantör

`PATCH /v1/buyer/work_order/work_orders/{id}` är avsiktligt smal: **endast `supplierFacilityId` och `supplierPrimaryContactEmail` läses från kroppen**. Alla andra fält du skickar ignoreras tyst istället för att avvisas.

```bash theme={null}
curl -X PATCH "$BASE/v1/buyer/work_order/work_orders/9001" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "supplierFacilityId": 3055, "supplierPrimaryContactEmail": "dispatch@newsupplier.com" }'
```

Två fallgropar:

* `supplierPrimaryContactEmail` gäller endast som en del av en omtilldelning. Att skicka den utan en leverantörsanläggningsändring gör att hela patchen blir en no-op: inget sparas och den aktuella arbetsordern returneras.
* Ett icke-existerande id och ett behörighetsavslag returnerar båda samma `400`-svar (unauthorized), så använd inte den här slutpunkten för att avgöra om en arbetsorder finns.

För att välja rätt leverantör programmatiskt, se [Leverantörsnätverk](/sv/buyer-api/supplier-network), som täcker den rangordnade slutpunkten för det privata nätverket.

## Köparens statusåtgärder

Fyra dedikerade slutpunkter flyttar en arbetsorder genom de köparägda delarna av livscykeln. Var och en tar samma kropp: arbetsorderns `id` och en valfri `note` som läggs till i tråden tillsammans med statusändringen.

| Slutpunkt                                            | Resulterande status        | Sidoeffekter                                                                                                                                  |
| ---------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `POST .../status_update/work_reviewed_and_completed` | `WorkReviewedAndCompleted` | Kan publicera leverantörens fakturautkast (enligt leverantörsinställningar) och uppfylla länkade inköpsförfrågningar.                         |
| `POST .../status_update/cancelled`                   | `CancelledWithReason`      | Avvisas med `409` medan en tekniker är incheckad, om ditt företag aktiverar [avbokningslåset](#avbokningslås-medan-en-tekniker-är-incheckad). |
| `POST .../status_update/work_unsatisfactory`         | `WorkUnsatisfactory`       | Skickar den bifogade anteckningen till leverantören.                                                                                          |
| `POST .../status_update/reopen`                      | Återöppnad                 | Skickar den bifogade anteckningen.                                                                                                            |

```bash theme={null}
curl -X POST "$BASE/v1/buyer/work_order/work_orders/status_update/work_reviewed_and_completed" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 9001,
    "note": {
      "text": "Verified on site, closing out.",
      "noteAddedBy": "ops@example.com",
      "noteAddedAt": "2026-08-21T09:00:00.000-07:00"
    }
  }'
```

Varje statusåtgärd returnerar den uppdaterade arbetsordern i standardhöljet.

### Avbokningslås medan en tekniker är incheckad

Företag kan aktivera ett avbokningslås som håller arbetsordrar öppna medan en tekniker är på plats. Med låset aktiverat avvisar OpenWrench varje avbokning med `409 Conflict` om en tekniker är aktivt incheckad på något av arbetsorderns servicebesök. Detta täcker besök på själva arbetsordern och besök på dess underentreprenad-arbetsordrar. OpenWrench blockerar på samma sätt avbokning av ett underkontrakt vars status propageras till rotarbetsordern, och sparar ingenting på någon av arbetsordrarna.

Låset konfigureras per köparföretag med två inställningar:

| Inställning                        | Standard | Effekt                                                                                                                                                             |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled`                          | `false`  | Slår på låset. Avstängt (standardvärdet) blockerar incheckningar aldrig avbokningar.                                                                               |
| `checkInConsideredStaleAfterHours` | `24`     | En öppen incheckning som är äldre än så här många timmar behandlas som en bortglömd utcheckning, inte pågående arbete, och slutar blockera avbokning på egen hand. |

Felmeddelandet i `409` identifierar den incheckade teknikern via e-post när besöket registrerade den:

```json theme={null}
{
  "message": "You can’t cancel this work order: technician tech@supplier.com is currently checked in."
}
```

När din integration får detta `409`, vänta tills teknikern checkar ut (eller tills incheckningen blir inaktuell) och försök igen, eller be leverantören avsluta besöket först. Låset är en del av ditt köparföretags arbetsorderkonfiguration i OpenWrench.

## Statusmodellen

`status`-värden du kommer att se och sätta via API:et:

| Status                                             | Ägs av       | Betydelse                                                                                                                                                                                                          |
| -------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Unassigned`                                       | Systemet     | Skapad, ingen leverantör tilldelad ännu.                                                                                                                                                                           |
| `PendingApproval`                                  | Köparen      | Väntar på internt godkännande, eller återförd hit efter att en leverantör tackat nej.                                                                                                                              |
| `SupplierInitiatedPendingApproval`                 | Köparen      | En leverantör öppnade den här arbetsordern på eget initiativ; den väntar på ditt godkännande innan leverantören bekräftas på den (hoppas över när ditt företag automatiskt godkänner leverantörsinitierat arbete). |
| `ConfirmedByServiceProvider`                       | Leverantören | Leverantören har accepterat jobbet.                                                                                                                                                                                |
| `TechAssigned`, `TechScheduled`, `TechRescheduled` | Leverantören | Servicebesök skapat eller (om)schemalagt.                                                                                                                                                                          |
| `TechWorkingOnSite`                                | Leverantören | Teknikern har checkat in.                                                                                                                                                                                          |
| `PartsRequested`, `PartsOnOrder`, `PartsReceived`  | Leverantören | Reservdelsanskaffning pågår.                                                                                                                                                                                       |
| `WaitingForReview`                                 | Leverantören | Arbetet är klart, väntar på din granskning.                                                                                                                                                                        |
| `WorkReviewedAndCompleted`                         | Köparen      | Du har granskat och stängt jobbet.                                                                                                                                                                                 |
| `WorkUnsatisfactory`                               | Köparen      | Du har avvisat det utförda arbetet.                                                                                                                                                                                |
| `CancelledWithReason`                              | Köparen      | Avbrutet.                                                                                                                                                                                                          |

De leverantörsägda övergångarna kommer in via leverantörens egen integration eller OpenWrench-apparna; din sida observerar dem via [webhooks](/sv/buyer-api/webhooks) eller polling (`statusChangedAt`, `statusChanges`) och agerar på de köparägda.

## Anteckningar

Arbetsordrar har en delad köpar–leverantör-anteckningstråd.

**Lägg till** med `PATCH /v1/buyer/work_order/work_orders/append_notes`. Kroppen är `{ "id": <woId>, "note": { ... } }` där anteckningen behöver `text` och `noteAddedBy`. Servern skriver över `noteAddedAt` med sin egen klocka, och författarens e-post läggs till i arbetsorderns lista över köparprenumeranter så att de får efterföljande aviseringar.

```bash theme={null}
curl -X PATCH "$BASE/v1/buyer/work_order/work_orders/append_notes" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 9001,
    "note": {
      "text": "Access code for the back door is 4417.",
      "noteAddedBy": "ops@example.com",
      "noteAddedAt": "2026-08-21T09:00:00.000-07:00"
    }
  }'
```

**Tagga personer i en anteckning** genom att lägga till `taggedUsers` bredvid `note`: en lista med kontakters e-postadresser att @omnämna. OpenWrench viker in varje e-postadress i `note.elements` som ett `user`-element, samma form som apparna skriver för ett @omnämnande, så du behöver inte bygga `elements`-strukturen själv. Taggade kontakter läggs till i arbetsorderns prenumerantlista om de inte redan prenumererar.

```bash theme={null}
curl -X PATCH "$BASE/v1/buyer/work_order/work_orders/append_notes" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 9001,
    "note": {
      "text": "Access code for the back door is 4417.",
      "noteAddedBy": "ops@example.com",
      "noteAddedAt": "2026-08-21T09:00:00.000-07:00"
    },
    "taggedUsers": ["tech@supplier.com", "manager@example.com"]
  }'
```

Regler för `taggedUsers`:

* E-postadresser trimmas och görs om till gemener innan matchning. En anteckning kan omnämna högst 25 användare.
* Dubbletter i listan, och användare som redan är taggade i `note.elements`, hoppas över istället för att omnämnas två gånger.
* En post som inte är en giltig e-postadress, eller en lista med fler än 25 e-postadresser, avvisas med `400` av typen `invalidInputDataException`. Ingenting sparas.
* En tom lista ignoreras. Att skicka `taggedUsers` utan ett `note`-objekt avvisas med `400`.

**Lägg till foton i bulk** med `PATCH /v1/buyer/work_order/work_orders/append_notes/bulk`. Använd den när du har en uppsättning foton att publicera (en teknikers före/efter-bilder, till exempel): prenumeranter får en enda grupperad avisering istället för en avisering per foto. Kroppen är `{ "id": <woId>, "notes": [ ... ] }` med 1–25 anteckningar, och varje anteckning måste bära en `photo`-URL och inget annat innehåll: `text` måste vara tomt och `video`, `audio`, `otherFile` och `elements` måste utelämnas. Att upprepa samma foto-URL i en begäran avvisas med `400`. Servern stämplar varje anteckning i batchen med samma `noteAddedAt` och bevarar ordningen du skickade dem i.

```bash theme={null}
curl -X PATCH "$BASE/v1/buyer/work_order/work_orders/append_notes/bulk" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "id": 9001,
    "notes": [
      { "text": "", "photo": "https://cdn.example.com/wo-9001/before.jpg" },
      { "text": "", "photo": "https://cdn.example.com/wo-9001/after.jpg" }
    ]
  }'
```

**Läs** med `GET /v1/buyer/work_order/work_order_notes/{woId}`. Detta returnerar bara den grundläggande köpar–leverantör-tråden (entreprenörs- och interna trådar är separata), och läsningen markerar anteckningarna som lästa för din kontakt. En nekad läsning returnerar en tom lista istället för ett fel.

## Etiketter

Etiketter är lätta taggar som ditt team definierar i OpenWrench-appen (ett namn plus en valfri färg). Via API:et kan du läsa katalogen och ersätta etiketterna som är applicerade på en arbetsorder. Att skapa eller redigera själva etiketterna sker fortfarande i appen.

**Bläddra i katalogen** med `GET /v1/buyer/work_order/work_order_labels`, eller hämta en med `GET /v1/buyer/work_order/work_order_labels/{id}`. Listan är avgränsad till ditt företags etiketter och pagineras med 10 per sida som standard. Den accepterar `search`- och `label`-filter på etikettexten. Skicka `no_pagination=true` för att hämta hela katalogen i ett anrop (sorteringen gäller fortfarande).

```bash theme={null}
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/work_order/work_order_labels?no_pagination=true"
```

**Ersätt en arbetsorders etiketter** med `PUT /v1/buyer/work_order/work_orders/{woId}/labels`. Kroppen är `{ "ids": [...] }` och det är en fullständig ersättning: etiketter som inte listas tas bort, och en tom array rensar dem alla. Svaret listar de etikettmappningar som nu är aktiva på arbetsordern.

```bash theme={null}
curl -X PUT "$BASE/v1/buyer/work_order/work_orders/9001/labels" \
  -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{ "ids": [4, 12] }'
```

Beteende att känna till:

* Ett saknat `ids` eller ett `ids` som inte är en array, eller ett id som inte är ett heltal, avvisas med `400`.
* Varje id måste vara en levande etikett från din egen katalog. Okända eller tenantöverskridande id:n svarar `400` med de felande id:na listade.
* Skrivningen kräver skrivbehörighet för arbetsordrar. Ett okänt, raderat eller främmande arbetsorder-id svarar med samma `400` som en nekad skrivning, inte en `404`.

## Problemtyper

`GET /v1/buyer/work_order/problem_types` listar de problemtyper som är konfigurerade för ditt företag. Cacha detta: du behöver ett giltigt `problemTypeId` för varje arbetsorder du skapar, och den rangordnade leverantörsslutpunkten tar också ett.

```bash theme={null}
curl -H "X-API-KEY: $KEY" -H "OW-KEY: $SECRET" \
  "$BASE/v1/buyer/work_order/problem_types"
```

## Sätta ihop det hela

En typisk utskicksintegration:

1. Cacha `me`, problemtyper och platser vid start.
2. Skapa arbetsordern med `supplierFacilityId` satt (eller skapa otilldelad, rangordna sedan leverantörer och `PATCH` tilldelningen).
3. Följ leverantörens framsteg via [webhooks](/sv/buyer-api/webhooks) (`workorder.status_update`), och hämta varje arbetsorder via id när en händelse kommer in. Behåll `GET /work_orders?statusChangedAt=...` som en gles avstämningskörning, inte som den primära signalen.
4. När leverantören når `WaitingForReview`, verifiera arbetet (se [Servicebesök](/sv/buyer-api/service-calls) för besöksbevis) och posta `work_reviewed_and_completed`, eller `work_unsatisfactory` med en anteckning.
5. Stäm av pengasidan genom [Offerter och förslag](/sv/buyer-api/quotes-and-proposals) och [Fakturor](/sv/buyer-api/invoices).
