Alterar nome ou foto do perfil

PATCH /inbox/profile

Muda um destes por pedido: o nome de perfil do WhatsApp (até 25 caracteres; o WhatsApp pode limitar quantas vezes muda) ou a foto (a api converte para JPEG 640x640). Mais de um campo responde 400 one_change_per_request. Responde a inbox, como GET /inbox/status.

Autenticação

[
  {
    "token": []
  }
]
{
  "token": {
    "name": "token",
    "type": "apiKey",
    "in": "header"
  }
}

Corpo da requisição

{
  "required": true,
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 1,
        "maxProperties": 1,
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 25,
            "description": "Novo nome do perfil."
          },
          "picture": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": false,
                "minProperties": 1,
                "maxProperties": 1,
                "properties": {
                  "url": {
                    "type": "string",
                    "description": "Link http(s) da imagem."
                  },
                  "base64": {
                    "type": "string",
                    "description": "A imagem em base64 (data URI também vale)."
                  }
                }
              },
              {
                "type": "null"
              }
            ],
            "description": "Foto nova (`url` ou `base64`); `null` tira a foto."
          }
        }
      }
    }
  }
}

Respostas

{
  "200": {
    "description": "A inbox depois da mudança.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/Inbox"
        }
      }
    }
  },
  "400": {
    "description": "Mais de um campo (`one_change_per_request`), corpo inválido, imagem que não deu para ler, ou o WhatsApp recusou (`whatsapp_rejected`; `field` diz qual).",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "invalid_request",
          "message": "Corpo inválido."
        }
      }
    }
  },
  "401": {
    "description": "Token ausente ou inválido.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unauthorized",
          "message": "Token inválido."
        }
      }
    }
  },
  "429": {
    "$ref": "#/components/responses/RateLimited"
  },
  "500": {
    "$ref": "#/components/responses/InternalError"
  },
  "501": {
    "description": "Na API oficial o perfil se altera pela Meta.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unsupported_for_channel",
          "message": "Não disponível neste canal."
        }
      }
    }
  },
  "503": {
    "description": "`disconnected`: a inbox está desconectada do WhatsApp.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "disconnected",
          "message": "Inbox desconectada do WhatsApp."
        }
      }
    }
  }
}

Estado: Disponível

Compatibilidade de canais

CanalCompatívelObservação
WhatsApp (Web)Sim
WhatsApp (API oficial)NãoSó no WhatsApp Web.
InstagramNão
MessengerNão
TelegramNão

Eventos que esta rota gera

Nenhum. Esta rota não gera evento no webhook (nem em GET /events): o resultado vem só na resposta.

Antes e depois (uazapi → Orkesio)

Na uazapi: POST /profile/name, POST /profile/image.

  • Um PATCH no lugar de duas rotas; um campo por pedido.
  • image → picture (url ou base64); remove → picture: null.
  • Responde a inbox (antes response em texto).

#/components/schemas/Inbox

{
  "type": "object",
  "required": [
    "id",
    "name",
    "status",
    "channel"
  ],
  "description": "Uma inbox: um número conectado a um canal.",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id da inbox (ex.: `r0269625d29bfbd`). É o `inbox_id` que o admin manda em `PATCH /inbox/admin-fields` e `POST /inbox/token/rotate`."
    },
    "name": {
      "type": "string",
      "description": "Nome da inbox, para você reconhecer. O WhatsApp não mostra este nome (o do celular é `system_name`)."
    },
    "token": {
      "type": "string",
      "description": "Token da inbox (header `token`). Só nas rotas do `admintoken` (`GET /inbox/all`, `POST /inbox/create`, `PATCH /inbox/admin-fields`); em `GET /inbox/status` não vem."
    },
    "status": {
      "type": "string",
      "enum": [
        "disconnected",
        "connecting",
        "connected",
        "hibernated"
      ],
      "description": "`disconnected`, `connecting` (esperando o QR code ou reconectando), `connected` ou `hibernated` (pausada pelo servidor). O mesmo valor do evento `inbox.status`; o porquê vem em `reason`. Na API oficial da Meta (WhatsApp, Messenger e Instagram), `disconnected` também quando a Meta recusou o token da inbox (vencido ou revogado) na última chamada: o `reason` é `token_expired`, o `last_disconnect_reason` começa com `190:` e volta a `connected` quando uma chamada passa ou com `POST /inbox/cloud` e um token novo. As duas viradas geram o evento `inbox.status`. Depois de um reinício do servidor, a inbox aparece `connected` até a próxima recusa."
    },
    "channel": {
      "type": "string",
      "enum": [
        "whatsapp_web",
        "whatsapp_cloud",
        "messenger",
        "instagram",
        "telegram"
      ],
      "description": "`whatsapp_web` (pareada por QR code ou código), `whatsapp_cloud` (API oficial do WhatsApp), `messenger` (uma Página do Facebook), `instagram` (um Instagram profissional, pela Página ligada a ele) ou `telegram` (um bot do Telegram e, com o Telegram Business, a conta ligada a ele)."
    },
    "phone": {
      "type": "string",
      "description": "Número conectado (só dígitos), quando conectada. Só WhatsApp: nos outros canais, `account_id`."
    },
    "account_id": {
      "type": "string",
      "description": "Messenger: o id da Página. Instagram: o id da conta profissional. Telegram: o id do bot. No WhatsApp não vem (o número está em `phone`)."
    },
    "profile_name": {
      "type": "string",
      "description": "Nome do perfil, quando conectada."
    },
    "profile_picture_url": {
      "type": "string",
      "description": "Foto do perfil, quando conectada."
    },
    "is_business": {
      "type": "boolean",
      "description": "Conta do WhatsApp Business."
    },
    "platform": {
      "type": "string",
      "description": "Aparelho principal (`android`, `ios`, `smba`...)."
    },
    "system_name": {
      "type": "string",
      "description": "**Só WhatsApp.** Nome que aparece no celular, em \"aparelhos conectados\".",
      "x-only": "whatsapp"
    },
    "admin_field_01": {
      "type": "string",
      "description": "Campo livre do administrador (referência do seu sistema). A inbox vê, só o `admintoken` altera."
    },
    "admin_field_02": {
      "type": "string",
      "description": "Segundo campo livre do administrador."
    },
    "last_disconnect_at": {
      "type": "string",
      "format": "date-time",
      "description": "Quando foi a última desconexão. ISO 8601 em UTC com milissegundos."
    },
    "last_disconnect_reason": {
      "type": "string",
      "description": "Motivo da última desconexão, em texto livre, sem formato estável (ex.: `connection attempt canceled by API`). Para tratar por código, use `reason`. O do banimento temporário começa com `402/` e traz o prazo (`expira em ...`) em português."
    },
    "created_at": {
      "type": "string",
      "format": "date-time",
      "description": "Criação. ISO 8601 em UTC com milissegundos."
    },
    "updated_at": {
      "type": "string",
      "format": "date-time",
      "description": "Última alteração. ISO 8601 em UTC com milissegundos."
    },
    "presence": {
      "type": "string",
      "enum": [
        "available",
        "unavailable"
      ],
      "description": "**Só WhatsApp.** Presença: `available` (aparece online) ou `unavailable`. Muda com `PATCH /inbox`.",
      "x-only": "whatsapp"
    },
    "reason": {
      "type": "string",
      "enum": [
        "qr",
        "pair_code",
        "logged_out",
        "banned",
        "plan_limit",
        "token_expired"
      ],
      "description": "Por que a inbox está nesse `status`, quando a api sabe: `qr` (conectando, esperando o QR code), `pair_code` (conectando, esperando o código de pareamento; o QR code vem junto), `logged_out` (desconectada porque o aparelho saiu: pelo celular, pelo WhatsApp ou por `POST /inbox/disconnect`; precisa de QR code de novo), `banned` (bloqueio temporário do WhatsApp), `token_expired` (na API oficial da Meta, a Meta recusou o token da inbox, vencido ou revogado: conecte de novo com `POST /inbox/cloud` e um token novo) ou `plan_limit` (hibernada porque o plano tem mais inboxes conectadas do que permite: troque de plano ou apague uma inbox). Sem ele, não há o que fazer além de esperar (reconectando, por exemplo). A lista pode crescer."
    },
    "qr_code": {
      "type": "string",
      "description": "**Só WhatsApp Web.** Só enquanto `status` é `connecting`. QR code para ler no celular (imagem PNG em base64, `data:image/png;base64,...`). Muda a cada poucos segundos: busque de novo em `GET /inbox/status`.",
      "x-only": "whatsapp_web"
    },
    "pair_code": {
      "type": "string",
      "description": "**Só WhatsApp Web.** Só enquanto `status` é `connecting`. Código de pareamento, quando a conexão foi pedida com `phone`. Digite no celular em \"Conectar com número de telefone\". O `qr_code` continua vindo junto: vale o que for usado primeiro.",
      "x-only": "whatsapp_web"
    },
    "history_request_id": {
      "type": "string",
      "description": "**Só WhatsApp Web.** Só na resposta de `POST /inbox/connect`: id desta tentativa de pareamento, o mesmo dos lotes de histórico e de `GET /inbox/history-sync`.",
      "x-only": "whatsapp_web"
    },
    "webhook_url": {
      "type": "string",
      "description": "Só nas inboxes oficiais, nas respostas da inbox do token (`GET /inbox/status`, `PATCH /inbox`, connect e disconnect): a URL de entrada que a Meta (ou o Telegram) chama, a mesma da resposta do `POST /inbox/cloud`. No painel da Meta, é a URL de callback. Não é um dos seus [`/webhooks`](/endpoint/get/webhooks)."
    },
    "verify_token": {
      "type": "string",
      "description": "Só nas inboxes oficiais, nas respostas da inbox do token (`GET /inbox/status`, `PATCH /inbox`, connect e disconnect): o token de verificação do webhook, o mesmo da resposta do `POST /inbox/cloud`."
    },
    "quality_rating": {
      "type": "string",
      "enum": [
        "green",
        "yellow",
        "red",
        "unknown"
      ],
      "description": "**Só API oficial.** No `GET /inbox/status` da inbox conectada, a qualidade do número na Meta (`green` alta, `yellow` média, `red` baixa, `unknown` ainda sem avaliação). Com `red` por 7 dias, a Meta baixa o nível de limite. Lida da Meta a cada 10 minutos; sem resposta dela, o campo não vem. A lista pode crescer.",
      "x-only": "whatsapp_cloud"
    },
    "messaging_limit_tier": {
      "type": "string",
      "example": "tier_2k",
      "description": "**Só API oficial.** No `GET /inbox/status` da inbox conectada, quantas pessoas a conta pode contatar primeiro (com modelo) em 24 horas, como a Meta informa: `tier_250`, `tier_2k`, `tier_10k`, `tier_100k` ou `tier_unlimited`. O nível é da conta da empresa na Meta e vale para todos os números dela. Lido a cada 10 minutos; sem resposta da Meta, o campo não vem.",
      "x-only": "whatsapp_cloud"
    },
    "resetting": {
      "type": "boolean",
      "description": "`true` enquanto o `POST /inbox/reset` roda; ausente fora dele."
    },
    "ai": {
      "allOf": [
        {
          "$ref": "#/components/schemas/AISettings"
        }
      ],
      "description": "Só no `GET /inbox/all`: a configuração da IA da inbox (a do `GET /chatbot/settings`, sem `last_error`)."
    },
    "queue": {
      "type": "object",
      "additionalProperties": false,
      "description": "Só no `GET /inbox/all`: a espera da fila (a do `GET /messages/queue/settings`).",
      "properties": {
        "delay_min_seconds": {
          "type": "integer",
          "minimum": 0
        },
        "delay_max_seconds": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "lead_fields": {
      "type": "array",
      "description": "Só no `GET /inbox/all`: os campos do lead que têm nome (os do `GET /leads/fields`).",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "key",
          "name"
        ],
        "properties": {
          "key": {
            "type": "string",
            "description": "`field01` a `field20`."
          },
          "name": {
            "type": "string"
          }
        }
      }
    }
  }
}

#/components/schemas/AISettings

{
  "type": "object",
  "description": "Configuração da IA na inbox.",
  "required": [
    "enabled",
    "ignore_groups",
    "stop_keyword",
    "stop_minutes",
    "pause_minutes_on_manual_reply",
    "has_openai_api_key",
    "notify_number",
    "notify_url",
    "max_replies_per_hour"
  ],
  "properties": {
    "enabled": {
      "type": "boolean",
      "description": "Liga ou desliga toda a automação: agentes, respostas rápidas por gatilho e fluxos. Desligada, `POST /chatbot/flows/start` e o webhook do fluxo respondem `409 chatbot_disabled`. Começa desligada."
    },
    "ignore_groups": {
      "type": "boolean",
      "description": "Não responde em grupos."
    },
    "stop_keyword": {
      "type": "string",
      "description": "Mensagem que, enviada inteira (sem diferença de maiúsculas) pelo contato ou por você à mão, pausa a IA naquele chat por `stop_minutes` e cancela os fluxos agendados para ele. Vazio desativa."
    },
    "stop_minutes": {
      "type": "integer",
      "minimum": 0,
      "description": "Por quantos minutos a `stop_keyword` pausa a IA no chat."
    },
    "pause_minutes_on_manual_reply": {
      "type": "integer",
      "minimum": 0,
      "description": "Quando alguém responde à mão (pelo celular ou WhatsApp Web), a IA pausa naquele chat por esses minutos. Mensagens enviadas pela API, inclusive as da própria IA, não pausam. `0` desativa."
    },
    "has_openai_api_key": {
      "type": "boolean",
      "description": "Se a chave da OpenAI da inbox está configurada. A chave nunca é devolvida."
    },
    "notify_number": {
      "type": "string",
      "description": "Número da equipe (com DDI) que recebe no WhatsApp o aviso de \"chamar humano\" (da IA ou do bloco do fluxo), do limite de respostas e da falha do provedor da IA, enviado pela própria inbox. A conversa com esse número fica fora de toda automação (não pausa, não arma silêncio, não responde). Vazio desliga.",
      "example": "5521999990000"
    },
    "notify_url": {
      "type": "string",
      "description": "URL que recebe o mesmo aviso por `POST`. Num tópico do ntfy (`https://ntfy.sh/seu-topico`), o aviso chega como notificação no celular; em outra URL, vai o JSON `{event, chatid, name, reason, owner, timestamp}`, com `event` `handoff` (chamaram uma pessoa), `reply_limit` (limite de respostas) ou `ai_error` (o provedor da IA falhou; no máximo um aviso por hora). Vazio desliga.",
      "example": "https://ntfy.sh/orkesio-seu-topico"
    },
    "max_replies_per_hour": {
      "type": "integer",
      "minimum": 0,
      "description": "Máximo de respostas da IA por conversa em uma hora (só conta resposta enviada). Ao passar, a automação daquela conversa (IA, gatilhos e fluxos) pausa por 1 hora, com o motivo em `chatbot_summary` enquanto durar, e a equipe é avisada. Protege de loop entre robôs e de abuso. `0` desliga; o padrão é `20`.",
      "example": 20
    },
    "last_error": {
      "type": "object",
      "description": "A última falha do provedor da IA (sem crédito, chave inválida, modelo inexistente…), em português. Some quando a IA volta a responder. Ausente sem falha.",
      "properties": {
        "at": {
          "type": "string",
          "format": "date-time",
          "description": "Quando. ISO 8601 em UTC com milissegundos."
        },
        "reason": {
          "type": "string",
          "description": "O motivo, em português.",
          "example": "A conta do provedor da IA está sem crédito."
        },
        "chat_id": {
          "type": "string",
          "description": "A conversa que ficou sem resposta."
        }
      },
      "required": [
        "at",
        "reason",
        "chat_id"
      ]
    }
  }
}

#/components/schemas/OrkesioError

{
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "description": "Código estável do erro, em inglês e `snake_case`. Os de uso geral: `invalid_request` (400): pedido inválido: JSON malformado, campo desconhecido ou valor fora do permitido (o detalhe em `message`; o campo em `field`, quando é um só); `unauthorized` (401): `token` ou `admintoken` ausente ou inválido; `forbidden` (403): o token não pode fazer isso (no servidor de demonstração, por exemplo); `not_admin` (403): o WhatsApp recusou por falta de permissão no grupo ou na newsletter; `account_restricted` (403): o WhatsApp restringiu a conta de iniciar conversas novas (mandar para quem já conversa continua valendo; até quando, em `GET /inbox/limits`); `new_chat_limit` (403): a conta atingiu a cota do WhatsApp de conversas novas neste ciclo (veja `GET /inbox/limits`); os dois também no `error` de `OrkesioMessage` e de `message.status`, e não adianta repetir o envio; `payment_required` (403): na API oficial, a Meta recusou o envio por um problema no pagamento da conta do WhatsApp Business (erro 131042 da Meta); acerte a forma de pagamento no gerenciador da Meta, porque repetir não adianta; também no `error` de `OrkesioMessage` e de `message.status`; `whatsapp_rejected` (400): o WhatsApp recusou a mudança pedida (o campo, em `field`, quando é um só); `not_found` (404): o recurso não existe nesta inbox; `conflict` (409): o recurso já existe ou mudou (id em uso, inbox de outro canal); `inbox_not_paired` (409): a inbox ainda não conectou um número; `payload_too_large` (413): o corpo passou do limite; `canceled` e `expired`: só no `error` de `OrkesioMessage` e de `message.status` (envio cancelado antes de sair, ou que passou do prazo na fila); `rate_limited` (429): muitos pedidos; espere o `Retry-After`; `internal_error` (500): falha inesperada na api; tente de novo; `send_failed` (500): o envio falhou (o motivo em `message`); também no `error` de `OrkesioMessage` e de `message.status`; `unsupported_for_channel` (501): o canal da inbox não atende esta rota ou este tipo de mensagem; `meta_error` (502): a Meta recusou ou não respondeu; `disconnected` (503): a inbox está desconectada (sem sessão do WhatsApp, ou token do canal oficial vencido); `unavailable` (503 ou 504): o WhatsApp não respondeu a tempo, ou algo em andamento impede agora; tente de novo. Cada rota lista os códigos próprios dela (`outside_window`, `number_invalid`, `flow_invalid`...). A lista pode crescer: trate código desconhecido pelo status HTTP."
    },
    "message": {
      "type": "string",
      "description": "Descrição para pessoas (às vezes o texto do WhatsApp ou da Meta). Não compare o texto: use `error`."
    },
    "field": {
      "type": "string",
      "description": "O campo do pedido que causou o erro, quando é um só (por exemplo, o campo que o WhatsApp recusou num `PATCH`)."
    }
  },
  "required": [
    "error",
    "message"
  ],
  "additionalProperties": true,
  "description": "O objeto de erro da Orkesio, o mesmo em todo lugar: o corpo das respostas de erro e o `error` de `OrkesioMessage`, `message.status` e `message.failed`. Algumas rotas juntam campos próprios (`request_id`, `errors`...)."
}

#/components/responses/RateLimited

{
  "description": "`rate_limited`: passou do limite de chamadas desta inbox (ou do admin); espere o tempo do header `Retry-After` e tente de novo.",
  "headers": {
    "Retry-After": {
      "description": "Segundos até poder chamar de novo.",
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  },
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/OrkesioError"
      },
      "example": {
        "error": "rate_limited",
        "message": "Muitas requisições."
      }
    }
  }
}

#/components/responses/InternalError

{
  "description": "`internal_error`: falha inesperada na api (no banco, por exemplo); tente de novo.",
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/OrkesioError"
      },
      "example": {
        "error": "internal_error",
        "message": "Falha inesperada."
      }
    }
  }
}

Guias relacionados

Visão geral · O que funciona em cada canal · O que muda da uazapi