Asynchronní podepisování souborů pomocí formuláře
Krok č. 1) Přihlášení
Pro přístup k API je nutné nejprve získat přístupový token pomocí koncového bodu pro přihlášení externího informačního systému pod identitou konkrétního uživatele.
Koncový bod: /api/sofa/v1/auth/extis/login-impersonate
Metoda: POST
Hlavičky:
- 
Accept: application/json 
- 
Content-Type: application/json 
Parametry:
- 
login … uživatelské jméno externího informačního systému. 
- 
password … heslo externího informačního systému. 
- 
impersonateUserId … LDAP identifikátor uživatele, jehož identitou má externí informační systém vystupovat (návod na zjištění tohoto identifikátoru je uveden v kapitole Postupy). 
Příklad:
POST /api/sofa/v1/auth/extis/login-impersonate HTTP/1.1
Host: sofaws.602.cz
Accept: application/json
Content-Length: …
Content-Type: application/json
{
  "login": "48a0ecdd540849f0af416307406467f0",
  "password": "wau3S99vx2d_NW2P",
  "impersonateUserId": "9e5f2f76-fff5-44c3-b943-06a95fdc08e2"
}Výsledek:
{
  "token": "eyJhbGciOiJBMjU2…"
}Krok č. 2) Nahrání souborů
V dalším kroku je nutné nahrát dokumenty jeden po druhém do výchozího úložiště (default) pomocí koncového bodu File API. Výsledkem bude seznam identifikátorů souborů použitý v dalším kroku.
Koncový bod: /api/sofa/v2/file?storeId=default
Metoda: POST
Hlavičky:
- 
Accept: application/json 
- 
Authorization: Bearer <token> 
- 
Content-Type: multipart/form-data 
Parametry:
- 
file … soubor dokumentu (ve verzi 2.0 se již nepoužívá hlavička FileId s parametry kódovanými ve formátu JSON, ale přenáší se standardní cestou pro upload souborů podle RFC 2854, tzn. že se název souboru uvádí v hlavičce Content-Disposition, velikost souboru v hlavičce Content-Length a typ souboru v hlavičce Content-Type). 
Příklad:
POST /api/sofa/v2/file?storeId=default HTTP/1.1
Host: sofaws.602.cz
Accept: application/json
Authorization: Bearer eyJhbGciOiJBMjU2…
Content-Length: …
Content-Type: multipart/form-data; boundary="-----086735ab-f408-405e-9628-4eb525d56d71"
-------086735ab-f408-405e-9628-4eb525d56d71
Content-Disposition: form-data; name="file"; filename="Document.pdf"
Content-Length: …
Content-Type: application/pdf
…binary file content…
-------086735ab-f408-405e-9628-4eb525d56d71--Výsledek:
{
  "fileId": "eyJhbGciOiJIUzI1…"
}Krok č. 3) Spuštění agendy
Pro spuštění podpisové agendy je nutné zavolat koncový bod GraphQL API s mutací pro zahájení agendy zprávou, které předáme identifikátor zprávy, identifikátor agendy (návod na zjištění tohoto identifikátoru je uveden v kapitole Postupy), seznam identifikátorů dokumentů z předchozího kroku, případně další JSON data nebo globální proměnné, pokud agenda nějaké používá. Výsledkem bude URL pro zobrazení podpisové agendy a seznam globálních proměnných, z nichž jedna bude použita pro URL, pomocí které lze čekat na dokončení operace.
JSONPath pro získání URL podpisové agendy pro přesměrování uživatele:
$.data.processes.sendMessageToAgendaEx.url
JSONPath pro získání URL pro zjištění výsledku operace/podepisování:
$.data.processes.sendMessageToAgendaEx.instance.variables[?(@.name == 'jobOperationUrl')].valueString
| Mutaci lze samozřejmě měnit dle potřeby. Níže uvedená varianta představuje minimalistickou verzi, která vrací pouze hodnoty potřebné pro zobrazení agendy a čekání na dokončení operace. | 
Koncový bod: /api/sofa/v1/graphql
Metoda: POST
Hlavičky:
- 
Accept: application/json 
- 
Authorization: Bearer <token> 
- 
Content-Type: application/json 
GraphQL operace:
mutation startAgenda(
  $messageIdent: String!
  $agendaIdent: String!
  $fileIds: [File_Id!]!
) {
  processes {
    sendMessageToAgendaEx(
      messageIdent: $messageIdent
      agendaIdent: $agendaIdent
      fileIds: $fileIds
    ) {
      instance {
        variables {
          name
          type
          valueString
        }
      }
      url
    }
  }
}Příklad:
POST /api/sofa/v1/graphql HTTP/1.1
Host: sofaws.602.cz
Accept: application/json
Authorization: Bearer eyJhbGciOiJBMjU2…
Content-Length: …
Content-Type: application/json
{
  "operationName": "startAgenda",
  "query": "mutation startAgenda(…",
  "variables": {
    "agendaIdent": "sys_agenda_signpoint_sdk",
    "messageIdent": "sys_start_template",
    "fileIds": [
      "eyJhbGciOiJIUzI1…"
    ]
  }
}Výsledek:
{
  "data": {
    "processes": {
      "sendMessageToAgendaEx": {
        "instance": {
          "variables": [
            {
              "name": "jobOperationUrl",
              "type": "STRING",
              "valueString": " https://sofa.602.cz/api/sofa/v1/operations/job?wait=true&operationToken=eyJhbGciOiJIUzI1…"
            },
            {
              "name": "jobOperationIdent",
              "type": "STRING",
              "valueString": "c0cdc7ed-d54c-457c-9f1e-c69bf5e8cd09"
            },
            {
              "name": "configSignatureWidth",
              "type": "STRING",
              "valueString": "300"
            },
            {
              "name": "configSignatureHeight",
              "type": "INTEGER",
              "valueString": null
            },
            {
              "name": "configSignaturePlaceholder",
              "type": "STRING",
              "valueString": "SIGN2"
            },
            {
              "name": "configUsePlaceholder",
              "type": "BOOLEAN",
              "valueString": null
            }
          ]
        },
        "url": "https://sofa.602.cz/GuestUser/GuestLogin?Token=eyJhbGciOiJIUzI1…"
      }
    }
  }
}Krok č. 4) Zobrazení agendy
Nejjednodušším krokem celého postupu je zobrazení agendy uživateli, kdy se pouze v prohlížeči otevře URL pro zobrazení agendy z předchozího kroku.
Příklad:
https://sofa.602.cz/GuestUser/GuestLogin?Token=eyJhbGciOiJIUzI1…Krok č. 5) Čekání na dokončení operace
Před stažením dokumentů opatřených podpisem je potřeba nejprve počkat, dokud uživatel požadované dokumenty nepodepíše. K tomu slouží URL adresa z výsledku GraphQL mutace z předchozího kroku, která vede na koncový bod Job Operations API, které slouží pro získání stavu probíhajících dlouhotrvajících operací. V případě zmíněné URL adresy se pro zjednodušení jedná o synchronní volání, tzn. že koncový bod nevrací výsledek ihned, ale snaží se počkat co nejdéle na dokončení probíhající operace. V případě chyby, dokončení operace nebo vypršení časového limitu se vrátí výsledek, který obsahuje stavovou informaci (state), která může nabývat jednu z následujících hodnot:
- 
done – operace byla úspěšně dokončena. 
- 
canceled – operace byla zrušena (uživatel zavřel formulář bez podepsání dokumentů). 
- 
error – došlo k chybě. 
- 
pending – operace stále probíhá. 
- 
deleted - vypršela platnost operace (doba platnosti: 4 hodiny). 
JSONPath pro získání stavu operace/podepisování:
$.state
JSONPath pro získání seznamu souborů (platné pouze pro stav done):
$.data.documents
Kromě stavu pending jsou všechny ostatní stavy konečné, tzn. že nemá smysl koncový bod volat znovu. V případě úspěšného dokončení operace (done) se navíc vrací strukturovaná data ve formátu JSON, která obsahují výsledek operace (závislý na agendě) obsahující identifikátory dokumentů opatřených podpisem doplněné o identifikátory původních dokumentů kvůli spárování.
Koncový bod: /api/sofa/v1/operations/job
Metoda: GET
Hlavičky:
- 
Authorization: Bearer <token> 
Příklad:
GET /api/sofa/v1/operations/job?wait=true&operationToken=eyJhbGciOiJIUzI1…
Host: sofaws.602.cz
Authorization: Bearer eyJhbGciOiJBMjU2…Výsledek v případě úspěšného dokončení operace:
{
  "id": "c0cdc7ed-d54c-457c-9f1e-c69bf5e8cd09",
  "type": "process-application",
  "state": "done",
  "data": {
    "documents": [
      {
        "signedFileId": "eyJhbGciOiJIUzI1…",
        "originalFileId": "eyJhbGciOiJIUzI1…",
        "filename": "Document.pdf",
        "orginalFilename": "Document.pdf"
      }
    ]
}Výsledek v případě stále probíhající operace:
{
  "id": "c0cdc7ed-d54c-457c-9f1e-c69bf5e8cd09",
  "type": "process-application",
  "state": "pending",
  "data": null
}Výsledek v případě zavření formuláře:
{
  "id": "c0cdc7ed-d54c-457c-9f1e-c69bf5e8cd09",
  "type": "process-application",
  "state": "canceled",
  "data": null
}Výsledek v případě chyby:
{
  "id": "c0cdc7ed-d54c-457c-9f1e-c69bf5e8cd09",
  "type": "process-application",
  "state": "error",
  "data": null
}Krok č. 6) Stažení souborů
Posledním krokem je stažení podepsaných souborů jeden po druhém pomocí koncového bodu File API:
Koncový bod: /api/sofa/v2/file
Metoda: GET
Hlavičky:
- 
Authorization: Bearer <token> 
Parametry:
- 
fileId … identifikátor stahovaného dokumentu. 
Příklad:
GET /api/sofa/v2/file?fileId=eyJhbGciOiJIUzI1…
Host: sofaws.602.cz
Authorization: Bearer eyJhbGciOiJBMjU2…Výsledek:
Výsledkem je stahovaný dokument.
| Název souboru lze získat buď standardně z hlavičky Content-Disposition, nebo File API v2 nastavuje pro snazší zpracování hlavičku X-Sofa-FileName. |