API v1 was built for the Android app: the app uses it to sign in, upload traces and read reports. There is no separate API key: a script signs in as the app, with username, password and the second-step code, and uses the token that the sign-in returns. This page shows the upload path with curl; the full contract, with every field and error code, is in API v1.
Before you start
- An account with two-step verification through the authenticator app and the terms accepted in the browser. Before acceptance, calls respond 403
termos_pendentes. - Signing in through the API counts toward the account limit of concurrent sessions, together with the browser and the app. With a limit of one session, signing in from the script ends the oldest session, such as the browser one.
curl,jqand bash on Linux. The examples use GNUstatanddd.
Do not store the password in the script, and keep the token like a password: with it, anyone can open your analyses until the session ends. When you are done, end the session.
Sign in and get the token
- Send username and password to receive the second-step challenge:
BASE=https://app.waitscope.com/api/v1 DESAFIO=$(curl -sS "$BASE/sessao" \ -H 'Content-Type: application/json' \ -d '{"username": "zz-exemplo", "password": "<password>", "method": "app", "device_name": "script"}' | jq -r .desafio) - Exchange the challenge and the 6-digit code from the authenticator app for the token:
TOKEN=$(curl -sS "$BASE/sessao/codigo" \ -H 'Content-Type: application/json' \ -d "{\"desafio\": \"$DESAFIO\", \"codigo\": \"123456\"}" | jq -r .token)
Result: TOKEN has 43 characters. It is valid for up to 90 days, expires after 30 days without use and appears in My account as App Android · script. The challenge is valid for 10 minutes.
To end the session when you are done:
curl -sS -X DELETE "$BASE/sessao" -H "Authorization: Bearer $TOKEN"
Upload the file
- Open the upload with the name and size of each file. With
"juntar": true, the files become a single analysis (analyze together):ARQ=exemplo-10046.trc TAM=$(stat -c %s "$ARQ") ENVIO=$(curl -sS "$BASE/envios" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/json' \ -d "{\"juntar\": false, \"arquivos\": [{\"nome\": \"$ARQ\", \"tamanho\": $TAM}]}" | jq -r .id)Result: the 201 response has the upload
id, each file with its positionnand what has already arrived inrecebido, andpedaco_max, 8388608 bytes (8 MiB). - Send the file in chunks of up to 8 MiB, in order, each with the
Content-Rangeof its range and the total size:PEDACO=8388608 INI=0 while [ "$INI" -lt "$TAM" ]; do FIM=$(( INI + PEDACO - 1 )) [ "$FIM" -ge "$TAM" ] && FIM=$(( TAM - 1 )) dd if="$ARQ" bs="$PEDACO" skip=$(( INI / PEDACO )) count=1 status=none | curl -fsS -X PUT "$BASE/envios/$ENVIO/arquivos/0" \ -H "Authorization: Bearer $TOKEN" \ -H 'Content-Type: application/octet-stream' \ -H "Content-Range: bytes $INI-$FIM/$TAM" \ --data-binary @- || break INI=$(( FIM + 1 )) doneResult: each accepted chunk responds 200 with the new total in
recebido. - Complete the upload and keep the analysis id:
ANALISE=$(curl -sS -X POST "$BASE/envios/$ENVIO/concluir" \ -H "Authorization: Bearer $TOKEN" | jq -r '.analises[0].id // .repetidas[0]')Result: the 201 response has the new analyses in
analisesand, inrepetidas, the ids of the ones that already existed with the same content (repeated upload).
If a chunk fails, the loop stops. Ask the server how much has arrived and run only the while again, which continues from that point:
INI=$(curl -sS "$BASE/envios/$ENVIO" -H "Authorization: Bearer $TOKEN" | jq '.arquivos[0].recebido')
Follow the analysis
- Ask for the status every few seconds:
curl -sS "$BASE/analises/$ANALISE" -H "Authorization: Bearer $TOKEN" | jq '{status, progress, error}'Result:
statusgoes fromqueuedtorunning, with the progress inprogress, and ends asdoneorerror, with the reason inerror. - With
done, download the report:curl -sS -o relatorio.html "$BASE/analises/$ANALISE/relatorio.html" -H "Authorization: Bearer $TOKEN"
relatorio.html is the same file as Download HTML in the console. The /relatorio route, with no extension, returns the report in JSON, section by section. Before the analysis finishes, or if it ended with an error, both respond 409 conflito.
Cancel and resume
DELETE $BASE/envios/$ENVIOcancels the upload and deletes what has arrived.- The upload belongs to the token that created it and disappears after 24 hours without a new chunk, or when the token session ends.
- Repeating
concluirreturns the same result, without creating the analysis again: you can repeat it after losing the response.
Common problems
| Response | Cause | What to do |
|---|---|---|
401 sessao_invalida | Token missing, expired or ended | Sign in again and use the new token. |
403 termos_pendentes | Terms not accepted in the current version | Open the console in the browser and accept them. |
409 conflito with recebido | The chunk does not start where the file stopped | Continue from the byte in recebido. |
413 grande_demais | The total exceeds the per-upload limit, or the chunk exceeds 8 MiB | Compress the file or use smaller chunks. |
429 limite | Queue full, stored analyses at the limit or another upload from the account in progress | Wait or delete analyses. With envio in the body, the half-finished upload belongs to this token: resume or cancel it. |
503 sem_espaco | Server out of disk space | Try again later and let the administrator know. |
Next steps
- Every field, route and error code: API v1.
- The limits of each account: limits and repeated upload.
- The same upload with a screen: upload through the browser.