Concluir o Challenge
curl --request POST \
--url https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue \
--header 'Client-Token: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"rawId": "<string>",
"type": "<string>",
"response": {
"authenticatorData": "<string>",
"clientDataJSON": "<string>",
"signature": "<string>",
"userHandle": "<string>"
}
}
'import requests
url = "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue"
payload = {
"id": "<string>",
"rawId": "<string>",
"type": "<string>",
"response": {
"authenticatorData": "<string>",
"clientDataJSON": "<string>",
"signature": "<string>",
"userHandle": "<string>"
}
}
headers = {
"Client-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Client-Token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
rawId: '<string>',
type: '<string>',
response: {
authenticatorData: '<string>',
clientDataJSON: '<string>',
signature: '<string>',
userHandle: '<string>'
}
})
};
fetch('https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'rawId' => '<string>',
'type' => '<string>',
'response' => [
'authenticatorData' => '<string>',
'clientDataJSON' => '<string>',
'signature' => '<string>',
'userHandle' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Client-Token: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Client-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue")
.header("Client-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Client-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_bodyInstance
Concluir o Challenge
Envia o resultado da resolução do passkey (assertion WebAuthn) para concluir a conexão da instância
POST
/
instances
/
{instanceId}
/
token
/
{token}
/
passkey-prologue
Concluir o Challenge
curl --request POST \
--url https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue \
--header 'Client-Token: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"id": "<string>",
"rawId": "<string>",
"type": "<string>",
"response": {
"authenticatorData": "<string>",
"clientDataJSON": "<string>",
"signature": "<string>",
"userHandle": "<string>"
}
}
'import requests
url = "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue"
payload = {
"id": "<string>",
"rawId": "<string>",
"type": "<string>",
"response": {
"authenticatorData": "<string>",
"clientDataJSON": "<string>",
"signature": "<string>",
"userHandle": "<string>"
}
}
headers = {
"Client-Token": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Client-Token': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
id: '<string>',
rawId: '<string>',
type: '<string>',
response: {
authenticatorData: '<string>',
clientDataJSON: '<string>',
signature: '<string>',
userHandle: '<string>'
}
})
};
fetch('https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'id' => '<string>',
'rawId' => '<string>',
'type' => '<string>',
'response' => [
'authenticatorData' => '<string>',
'clientDataJSON' => '<string>',
'signature' => '<string>',
'userHandle' => '<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Client-Token: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue"
payload := strings.NewReader("{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Client-Token", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue")
.header("Client-Token", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.z-api.io/instances/{instanceId}/token/{token}/passkey-prologue")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Client-Token"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"id\": \"<string>\",\n \"rawId\": \"<string>\",\n \"type\": \"<string>\",\n \"response\": {\n \"authenticatorData\": \"<string>\",\n \"clientDataJSON\": \"<string>\",\n \"signature\": \"<string>\",\n \"userHandle\": \"<string>\"\n }\n}"
response = http.request(request)
puts response.read_bodyConceituação
Em alguns dispositivos, o WhatsApp passou a exigir uma verificação adicional ao tentar conectar ao WhatsApp, chamada de Chave de Acesso (Passkey). Devido a isso, tais dispositivos, quando tentarem ler o QR Code podem receber o retorno do Challenge.
- O endpoint de QR Code é chamado e retorna um
challenge. - Esse challenge é resolvido no dispositivo / autenticador (procedimento feito fora do Z-API, e que não depende da nossa API).
- O resultado dessa resolução (a assertion WebAuthn) é enviado para este endpoint, para que a instância conclua a conexão.
A resolução do challenge acontece diretamente entre o dispositivo do usuário e o autenticador (Passkey), fora do ecossistema Z-API. Este endpoint apenas recebe o resultado já processado.Pensando nessa nova autenticação do WhatsApp, o Z-API criou uma extensão chamada Z-API Connector, justamente para facilitar essa validação da Chave de Acesso.
Atributos
Obrigatórios
string
obrigatório
ID da sua instância. Disponível no painel Z-API em Instâncias.
string
obrigatório
Token da sua instância Z-API.
Obrigatórios
string
obrigatório
Identificador da credencial gerada pelo autenticador
string
obrigatório
Identificador bruto (raw) da credencial
string
obrigatório
Tipo da credencial. Sempre “public-key”
object
obrigatório
Dados da assinatura WebAuthn retornados pelo autenticador
Mostrar Propriedades do response
Mostrar Propriedades do response
Opcionais
object
Extensões do cliente retornadas pelo autenticador
Mostrar Propriedades do clientExtensionResults
Mostrar Propriedades do clientExtensionResults
array
Métodos de verificação de usuário utilizados durante a assertion
Request Body
{
"id": "...",
"rawId": "...",
"type": "public-key",
"response": {
"authenticatorData": "...",
"clientDataJSON": "...",
"signature": "...",
"userHandle": null
},
"clientExtensionResults": { "uvm": [] }
}
Response
200
Retorna o resultado do processamento da assertion pelo middleware da instância. Existem três variações possíveis: Sucesso:{ "success": true }
{ "success": false, "reason": "assertion (rawId + response) is required" }
{ "success": false, "reason": "assertion fields must be strings" }
Respostas com
success: false indicam que o payload da assertion está malformado — é necessário corrigir o corpo enviado e reenviar. Não se trata de um erro de infraestrutura do Z-API.400
Retornado nos seguintes casos:- Instância não encontrada para o par
instanceId+token:
{ "error": "Instance not found", "value": null }