# Opprette en forespørsel

Oppdag et skjemas feltnøkler, og opprett deretter en forespørsel med forhåndsutfylte verdier, låste felt og context.

## Opprette en forespørsel

To API-kall: spør skjemaet hva det kan fortelles, og tildel det deretter til én person med verdiene du allerede kjenner til.

<h2 id="start-in-the-share-sheet">Start i Del-vinduet</h2>

<p>
  Åpne det publiserte skjemaet ditt, klikk <strong>Del</strong>, og velg fanen <strong>Forespørsler</strong>. Kortet der gir deg alt du
  trenger for å gjøre det første kallet:
</p>

<ul>
  <li>
    <strong>Skjema-ID-en</strong>, med en kopiknapp.
  </li>
  <li>
    Et <strong>curl</strong>-utdrag og en <strong>MCP</strong>-prompt, begge bygget fra skjemaets faktiske feltnøkler — så eksempelet er
    allerede adressert til feltene dette skjemaet faktisk har.
  </li>
  <li>
    En <strong>Manuell</strong>-fane som oppretter én forespørsel for hånd, og <strong>Prøv det selv</strong>, som gjør det du fylte inn der
    om til en forespørsel i <a href="#test-mode">testmodus</a> og gir deg lenken.
  </li>
  <li>
    En lenke videre til <a href="/no/requests/managing-requests">Forespørsler-siden</a>, filtrert til dette skjemaet.
  </li>
</ul>

> ⚠️ **Publiser først**
> <p>
>     Et upublisert skjema kan ikke få forespørsler, og utdragene forblir deaktivert til du publiserer. Feltnøkler fryses ved første
>     publisering — det er dette som lar automatiseringen din fortsette å adressere <code>company_name</code> et år senere. Se{' '}
>     <a href="/no/requests/field-keys">Feltnøkler</a>.
>   </p>

<h2 id="discover-fields">Steg 1 — Oppdag feltene</h2>

<p>
  <code>fields.list</code> returnerer hvert felt i skjemaets nåværende publiserte versjon, med nøkkelen du adresserer det med, formen
  verdien tar, og hvilken bøtte det tilhører.
</p>

```
curl -X POST https://api.formstep.io/api/v1 \
  -H "Authorization: Bearer $FORMSTEP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method":"fields.list","params":{"formId":"j57..."}}'
```

```
{
  "ok": true,
  "data": {
    "published": true,
    "items": [
      { "key": "company_name", "type": "text", "title": "Company", "required": true, "prefillable": true },
      {
        "key": "company_size", "type": "select", "title": "Company size", "required": false, "prefillable": true,
        "options": [
          { "key": "1_50", "label": "1–50" },
          { "key": "51_200", "label": "51–200" }
        ]
      },
      { "key": "case_id", "type": "hidden", "title": "Case", "required": false, "prefillable": false, "context": true },
      { "key": "total", "type": "number", "title": "Total", "required": false, "prefillable": false, "calculated": true },
      { "key": "signature", "type": "signature", "title": "Sign here", "required": true, "prefillable": false }
    ],
    "hasMore": false
  }
}
```

<ul>
  <li>
    <code>context: true</code> merker et skjult felt. Verdien går i <code>context</code>, aldri i <code>prefill</code>; et skjult felts
    nøkkel i <code>prefill</code> avvises med <code>UNKNOWN_FIELD_KEY</code>.
  </li>
  <li>
    <code>calculated: true</code> merker et beregnet felt. Skjemaet regner ut verdien selv, så ingen kan sende inn en; du leser den tilbake
    under nøkkelen sin i <code>answers</code>.
  </li>
  <li>
    <code>prefillable: false</code> merker et felt ingen kan oppgi en verdi for: filopplasting, signatur, betaling, avtalebooking, og
    dokumentblokker. Mottakeren fyller ut spørsmålene selv. Skjulte felt og beregnede felt viser også <code>prefillable: false</code>:{' '}
    skjulte felt tar <code>context</code>, og beregnede felt tar ingenting.
  </li>
  <li>
    <code>options</code> lister valgene for et valgspørsmål. Send valgets <strong>nøkkel</strong>, ikke etiketten; etiketten er der slik at
    du kan koble valget du kjenner til, mot nøkkelen. En matrise lister sine <code>rows</code> og <code>columns</code> på samme måte.
  </li>
  <li>
    Gjentakende grupper kommer tilbake som én oppføring med <code>type: "group"</code>, <code>repeating: true</code>, og en liste med{' '}
    <code>members</code>.
  </li>
</ul>

<h2 id="create">Steg 2 — Opprett forespørselen</h2>

```
curl -X POST https://api.formstep.io/api/v1 \
  -H "Authorization: Bearer $FORMSTEP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"method":"requests.create","params":{
        "formId":"j57...",
        "recipient":{"email":"ada@acme.com","name":"Ada"},
        "context":{"case_id":"CASE-9"},
        "prefill":{"company_name":"Acme","company_size":"51_200"},
        "readonly":["company_name"],
        "delivery":"email",
        "externalId":"run-42",
        "callbackUrl":"https://automation.example/webhook/resume-abc",
        "idempotencyKey":"run-42"}}'
```

```
{
  "ok": true,
  "data": {
    "id": "kd7...",
    "status": "pending",
    "url": "https://form.formstep.io/r/rq_...",
    "deliveryStatus": "queued",
    "expiresAt": 1794787200000,
    "createdAt": 1789379200000,
    "externalId": "run-42",
    "deduplicated": false
  }
}
```

<p>
  <code>deliveryStatus</code> er <code>"queued"</code> når Formstep sender invitasjonen på e-post, og <code>"not_requested"</code> når du
  leverer lenken selv.
</p>

<h2 id="three-buckets">Prefill, låste felt, og context</h2>

<p>Tre ulike ting kan knyttes til en forespørsel, og å blande dem sammen er den vanligste første feilen.</p>

<h3 id="prefill">Prefill</h3>

<p>
  Startsvar for de synlige spørsmålene, slik at mottakeren gjennomgår og retter i stedet for å skrive fra bunnen. Alt du allerede vet om dem
  hører hjemme her — firmanavnet fra CRM-et ditt, beløpet fra fakturaen, fjorårets svar.
</p>

<h3 id="locked-fields">Låste felt</h3>

<p>
  List opp en forhåndsutfylt nøkkel i <code>readonly</code>, så ser mottakeren verdien, men kan ikke endre den. Bruk det for fakta de
  bekrefter i stedet for oppgir — kontraktsnummeret, den avtalte prisen. Låsing gjelder per forespørsel: selve skjemaet er urørt, og det
  samme feltet er fritt redigerbart på neste forespørsel.
</p>

<p>
  Hver låst nøkkel må også være forhåndsutfylt, og et låst, <em>obligatorisk</em> felt må forhåndsutfylles med noe som ikke er tomt — ellers
  ville mottakeren stå overfor et skjema de aldri kunne sende inn, og Formstep avviser kallet i stedet for å skape den fellen.
</p>

<h3 id="context">Context</h3>

<p>
  Tiltrodde verdier for skjemaets <a href="/no/building-forms/hidden-fields">skjulte felt</a> — et saksnummer, en kjørings-ID, et beløp.
  Context mater variabler, betinget logikk, beregnede felt og e-posttekst, kommer uendret tilbake i callbacken, og mottakeren kan ikke endre
  den. Det siste er forskjellen fra å så et skjult felt gjennom en URL på en offentlig lenke, der hvem som helst kan redigere
  spørrestrengen; forespørselslenker ignorerer URL-spørringsparametere fullstendig. Context-verdier må være en streng, et tall, eller en
  boolsk verdi.
</p>

<p>
  Context er ikke fritekst: hver nøkkel må være et skjult felt i skjemaets publiserte versjon, og enhver annen nøkkel avvises med{' '}
  <code>UNKNOWN_FIELD_KEY</code>. Bokføring uten et skjult felt, som en kjørings-ID, hører i stedet hjemme i{' '}
  <a href="#metadata">metadata</a>.
</p>

<p>
  Skjulte felt vises ikke på skjemaet, men en context-verdi er ikke hemmelig for mottakeren, som ser den overalt hvor skjemaet eller
  invitasjonen viser den: en <a href="/no/building-forms/answer-piping">omtale</a> i skjemainnholdet eller e-postteksten, eller et synlig
  spørsmål som bruker det skjulte feltet som sin <a href="/no/building-forms/field-configuration#default-values">standardverdi</a>. I det
  siste tilfellet ser mottakeren context-verdien forhåndsutfylt i det spørsmålet og kan redigere svaret. Selve context-verdien forblir
  uendret. En <code>prefill</code> for spørsmålets egen nøkkel vinner over standardverdien.
</p>

<h3 id="metadata">Metadata</h3>

<p>
  Din egen bokføring — en kjørings-ID, en CRM-post-ID. Den når aldri selve skjemaet, så den kan ikke pipes inn i tekst eller leses av
  logikk; den blir bare med og kommer tilbake i hver callback og statusavlesning.
</p>

<h2 id="value-shapes">Verdiformer</h2>

<p>
  Send verdier i formen <code>type</code> fra <code>fields.list</code> ber om. Feil form kommer tilbake som en valideringsfeil som navngir
  nøkkelen, forventet type, og — for valgspørsmål — verdiene som ville blitt godtatt.
</p>

<h2 id="documents">Dokumenter</h2>

<p>
  En <a href="/no/building-forms/documents-block">dokumentblokk</a> gir filer til respondenten. De opprinnelige filene er de samme for alle
  og blir alltid værende; en forespørsel legger til filer for sin ene mottaker under dem — kundens egen leiekontrakt, en kopi av ID-en å
  sjekke. Bytes reiser aldri gjennom selve API-kallet: last opp først, referer deretter.
</p>

```
"documents": [
  { "documentId": "kn7...", "name": "Your lease contract" },
  { "documentId": "kn8..." }
]
```

<p>
  <code>name</code> overstyrer visningsnavnet som ble lagret ved opplastingen. Har skjemaet mer enn én dokumentblokk, angir du målet med
  <code>field</code>, blokkens feltnøkkel (<code>fields.list</code> viser den, sammen med de faste dokumentene alle respondenter allerede
  får). Filene havner under de faste dokumentene: en forespørsel legger til filer, den erstatter aldri noen.
</p>

<p>
  Grenser: bare PDF og bilder, 25 MB per dokument, 100 MB per forespørsel (<code>DOCUMENTS_TOO_LARGE</code>), og maks 20 dokumenter per
  blokk medregnet de faste (<code>DOCUMENTS_TOO_MANY</code>). Filene teller mot arbeidsområdens lagringskvote og frigjøres når forespørslene
  som refererer dem, faller ut av skjemaets oppbevaringsperiode. Innsendingen registrerer listen mottakeren så under blokkens feltnøkkel, så
  callbacken forteller deg nøyaktig hvilke filer denne personen fikk.
</p>

<h2 id="options">Resten av alternativene</h2>

<h3 id="test-mode">Testmodus</h3>

<p>
  Send <code>test: true</code> for å prøve ut hele koblingen før en ekte kjøring. En testforespørsel er ekte på alt som betyr noe for
  koblingen: lenken åpnes og kan fullføres, <a href="/no/requests/callbacks">callbacken</a> fyrer som vanlig, og <code>requests.get</code>{' '}
  returnerer svarene. Det den aldri gjør, er å nå noen eller noe du måtte rydde opp etter:
</p>

<ul>
  <li>
    Ingen invitasjon og ingen påminnelse sendes, uansett hva <code>delivery</code> sier. <strong>Send påminnelse</strong> avvises på den, og
    den bruker ingenting av din månedlige kvote.
  </li>
  <li>
    Callbacken bærer <code>"test": true</code>, slik at arbeidsflyten din kan forgrene seg på det eller ignorere hendelsen.
  </li>
  <li>
    Innsendingen lagres, men teller ikke: verken mot din månedlige kvote (en test fullføres selv når kvoten er brukt opp), og den vises
    aldri i skjemaets innsendingstall, innsendinger-fanen, eksporter, eller integrasjonene dine. Ingen blir varslet.
  </li>
  <li>
    Forespørselen er skjult fra <a href="/no/requests/managing-requests">Forespørsler-siden</a> bak <strong>Vis testforespørsler</strong>,
    utelatt fra forespørselstrakten i Analyse, og utelatt fra <code>requests.list</code>-svaret med mindre du sender{' '}
    <code>includeTest: true</code> som parameter.
  </li>
  <li>
    Lenken lukkes innen 24 timer, selv når <code>expiresAt</code> ber om lengre tid; <code>expiresAt</code> i svaret sier når. På Free kan
    et workspace opprette 10 testforespørsler per dag. Den neste feiler med <code>RATE_LIMITED</code> og årsaken{' '}
    <code>TEST_REQUEST_LIMIT_REACHED</code>, og <code>retryAfterMs</code> sier når du kan prøve igjen. Pro og Business har ingen daglig
    grense.
  </li>
</ul>

<p>
  <strong>Prøv det selv</strong> i Del-vinduet er denne modusen med ett klikk: den tar utkastet fra Manuell-fanen, lar mottaker og levering
  stå tomt, og gir deg lenken å åpne selv.
</p>

<h3 id="allowance">Hva en forespørsel koster</h3>

<p>
  Hver plan har én <strong>månedlig kvote</strong> som deles av begge kanaler: en innsending via offentlig lenke bruker én enhet, og det
  gjør også hver forespørsel du oppretter — uansett om mottakeren svarer, ignorerer den, eller du kansellerer den. Innsendingen en
  forespørsel samler inn er allerede betalt for og teller ingen steder. Gratis inkluderer 1 000 enheter i måneden, Pro og Business 50 000.
  Ved taket mislykkes <code>requests.create</code> med <code>UPGRADE_REQUIRED</code> og årsak <code>MONTHLY_ALLOWANCE_REACHED</code>;
  forespørsler du allerede har opprettet, kan fortsatt besvares.
</p>

<p>
  På Gratis bruker en forespørsel opprettet med <code>"delivery": "email"</code> også én av kontoens{' '}
  <a href="/no/subscription-billing/limits-quotas#free-invitations">10 gratis invitasjoner</a>. De nullstilles aldri; når de er brukt opp,
  mislykkes e-postlevering med <code>UPGRADE_REQUIRED</code> og årsak <code>FREE_INVITATIONS_USED</code>.
</p>

<h3 id="idempotency">Idempotens</h3>

<p>
  Send den samme <code>idempotencyKey</code> med den samme forespørselskroppen, og du får den opprinnelige forespørselen tilbake, med{' '}
  <code>deduplicated: true</code> og den opprinnelige lenken — ingen ny forespørsel, ingen ny e-post. Gjenbruk nøkkelen med en{' '}
  <em>annen</em> forespørselskropp, og Formstep avviser med <code>IDEMPOTENCY_CONFLICT</code> i stedet for å gjette hvilken du mente. Nøkler
  gjelder per arbeidsområde og respekteres i 30 dager; etter det starter samme nøkkel en ny forespørsel.
</p>

<p>
  I et arbeidsflytverktøy er kjørings-ID-en den naturlige nøkkelen: en kjøring som prøves på nytt etter et nettverksglipp, plukker opp
  forespørselen den allerede opprettet.
</p>

<h3 id="rate-limit">Hastighetsbegrensning</h3>

<p>
  <code>requests.create</code> og <code>documents.create</code> deler et budsjett på <strong>60 kall i minuttet</strong>, telt per API-token
  (eller per bruker, ved et kall gjort uten ett). En etterslep du tømmer, bør holde sitt eget tempo; en byge over budsjettet avvises, men
  kan prøves på nytt.
</p>

<h3 id="custom-domains">Egendefinerte domener</h3>

<p>
  Hvis skjemaet allerede er publisert på ett av dine <a href="/no/branding-domains/custom-domains">egendefinerte domener</a>, utstedes
  forespørselslenker der automatisk — <code>https://forms.dittselskap.com/r/rq_…</code>. Navngi <code>domainId</code> eksplisitt når
  skjemaet er publisert på mer enn ett. Domenet må tilhøre samme arbeidsområde som skjemaet.
</p>

<h2 id="what-the-recipient-sees">Hva mottakeren ser</h2>

<p>
  Nøyaktig skjemaet du utformet — samme tema, samme logo, samme språk — med verdiene deres på plass, låste felt skrivebeskyttet, og ingen
  captcha å løse. Når de sender inn, får de din takkeside. Kommer de tilbake til lenken etterpå, får de resultatsiden i stedet for et tomt
  skjema.
</p>

<p>
  Det finnes ingen melding fra automatiseringen din på siden. Alt mottakeren trenger å bli fortalt hører hjemme i selve skjemaet, der du kan
  personalisere det ved å <a href="/no/building-forms/answer-piping">nevne</a> en context-verdi eller et forhåndsutfylt felt.
</p>

<p>
  En AI-agent følger de samme to stegene som <code>fields_list</code> og <code>request_create</code>, med de samme alternativene — inkludert
  documents og <code>domainId</code>. Se <a href="/no/developers/mcp-server#requests">Forespørsler på MCP-serveren</a>.
</p>

<div class="not-prose grid gap-3 sm:grid-cols-2">
  - [Feltnøkler](/no/requests/field-keys) — Hvor de nøklene kommer fra og hvordan holde dem stabile.
  - [Callbacks og signering](/no/requests/callbacks) — Hva som kommer når mottakeren er ferdig.
  - [Feilsøking](/no/requests/troubleshooting) — Hver avvisningsgrunn og hva du skal gjøre med den.
  - [API-referanse](/no/developers/rest-api) — Full parameterliste for hver forespørselsmetode.
</div>
