{"openapi":"3.1.0","info":{"title":"Socialfy Nexus API","version":"1.0.0","license":{"name":"Proprietary","url":"https://www.socialfy.me/"},"description":"Superfície técnica sanitizada e derivada do catálogo canônico das rotas Express. A versão 1.0.0 publica seis operações estáveis para instâncias QR. A criação e as operações públicas permanecem restritas a WhatsApp por QR. Outras conexões podem aparecer somente como estado observado em capabilities. Referência atualizada em 2026-09-08 12:20 BRT."},"externalDocs":{"description":"Guias e conceitos Nexus","url":"/docs/nexus"},"servers":[{"url":"https://nexus.socialfy.me","description":"Produção — não usar para testes"}],"x-nexus-connection-matrix":{"whatsapp_qr":{"label":"WhatsApp por QR","availability":"supported","creatable":true},"conexao_oficial":{"label":"Conexão oficial","availability":"observable","creatable":false},"conexao_hibrida":{"label":"Conexão híbrida","availability":"observable","creatable":false},"conexao_unificada":{"label":"Conexão unificada","availability":"observable","creatable":false},"conexao_indisponivel":{"label":"Conexão indisponível","availability":"observable","creatable":false}},"x-api-key-lifecycle":{"creation":"Painel autenticado; secret exibido uma única vez.","scope":"Uma instância e seu tenant.","rotation":"Substituição imediata do hash; a chave anterior deixa de autenticar.","expiration":"Não há expiração automática neste contrato; rotacione periodicamente conforme a política de segurança da integração.","revocation":"A rotação substitui o hash imediatamente e invalida a chave anterior; não há endpoint público separado de revogação."},"x-pagination-policy":{"style":"cursor","parameters":["cursor","limit"],"note":"Nenhuma operação desta superfície inicial é paginada. Novas listas devem adotar este contrato único."},"x-rate-limit-policy":{"enforcedAtHttpContract":false,"responseHeaders":[],"futureHeaders":["RateLimit-Limit","RateLimit-Remaining","RateLimit-Reset","Retry-After"],"note":"O runtime possui controles internos de fila e autenticação, mas esta superfície ainda não promete uma cota HTTP nem headers RateLimit. O contrato deve ser promovido junto com a implementação real."},"x-media-policy":{"publicSurface":"text-only","note":"Uploads, downloads, MIME e limites por conexão permanecem fora da superfície estável inicial."},"x-api-lifecycle":{"breakingChanges":"Exigem nova versão major e migration guide.","deprecation":"Usa deprecated=true, data, substituto e janela mínima antes da remoção.","changelog":"/docs/nexus/desenvolvedores"},"paths":{"/api/nexus/capabilities":{"get":{"tags":["Connections"],"summary":"Listar recursos por tipo de conexão","description":"Retorna o catálogo de recursos disponíveis para cada tipo de conexão homologado.","operationId":"listChannelCapabilities","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/comecando/escolher-conexao"},"security":[],"parameters":[],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelCapabilitiesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"}}},"/api/wa/instances":{"post":{"tags":["Instances"],"summary":"Criar uma instância","description":"Cria uma instância tenant-scoped. O identificador escolhido pelo cliente funciona como chave natural; repetição devolve conflito e nunca autoriza forceNew implícito.","operationId":"createInstance","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/instancias/criar-instancia"},"security":[{"NexusUserBearer":[]}],"parameters":[],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstanceResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInstanceRequest"}}}},"x-idempotency":{"mode":"resource-key","field":"instanceId","conflictStatus":409}}},"/api/wa/status/{instanceId}":{"get":{"tags":["Instances"],"summary":"Consultar o status de uma instância","description":"Consulta o estado do transporte. Um status persistido ou HTTP 200 isolado não substitui a verificação de readiness e entrega.","operationId":"getInstanceStatus","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/instancias/criar-instancia"},"security":[{"NexusUserBearer":[]},{"InstanceApiKey":[]}],"parameters":[{"name":"instanceId","in":"path","required":true,"schema":{"$ref":"#/components/schemas/InstanceId"}}],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceStatusResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"}}},"/api/nexus/instances/{publicInstanceId}/capabilities":{"get":{"tags":["Instances"],"summary":"Consultar capabilities efetivas da instância","description":"Cruza os recursos da conexão com o estado atual da conta e da sessão.","operationId":"getInstanceCapabilities","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/instancias/criar-instancia"},"security":[{"NexusUserBearer":[]},{"InstanceApiKey":[]}],"parameters":[{"name":"publicInstanceId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstanceCapabilitiesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"}}},"/api/send":{"post":{"tags":["Messages"],"summary":"Enviar uma mensagem de texto","description":"Enfileira uma mensagem de texto para um destinatário E.164. O mesmo Idempotency-Key reaproveita a intenção existente em vez de duplicar o envio.","operationId":"sendTextMessage","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/mensagens/enviar-mensagem"},"security":[{"NexusUserBearer":[]},{"InstanceApiKey":[]}],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendTextMessageRequest"}}}},"x-idempotency":{"mode":"header","header":"Idempotency-Key"}}},"/api/wa/instances/{id}/settings":{"patch":{"tags":["Webhooks"],"summary":"Configurar o webhook da instância","description":"Atualiza somente os campos de webhook enviados. A ativação continua condicionada a feature flag, allowlist do tenant e validação SSRF do destino.","operationId":"configureInstanceWebhook","externalDocs":{"description":"Guia na Central de Ajuda","url":"/docs/nexus/webhooks/configurar-webhook"},"security":[{"NexusUserBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"$ref":"#/components/schemas/InstanceId"}}],"responses":{"200":{"description":"Operação concluída.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSettingsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/Conflict"},"500":{"$ref":"#/components/responses/InternalError"}},"x-release-state":"public","x-nexus-connection-support":{"whatsapp_qr":"supported"},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSettingsRequest"}}}},"x-idempotency":{"mode":"convergent-patch"},"callbacks":{"instanceEvents":{"{$request.body#/cfgWebhookUrl}":{"post":{"operationId":"receiveNexusInstanceEvent","summary":"Receber um evento assinado do Nexus","description":"Valide X-Nexus-Signature sobre o corpo bruto antes de transformar o JSON. Deduplicate pelo identificador do evento quando ele existir.","parameters":[{"$ref":"#/components/parameters/WebhookSignature"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"}}}},"responses":{"204":{"description":"Evento aceito para processamento assíncrono."},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}}}}}}},"tags":[{"name":"Connections","description":"Recursos disponíveis por tipo de conexão.","externalDocs":{"url":"/docs/nexus/comecando/escolher-conexao"}},{"name":"Instances","description":"Criação, estado e readiness de instâncias.","externalDocs":{"url":"/docs/nexus/instancias"}},{"name":"Messages","description":"Envio idempotente e acompanhamento de mensagens.","externalDocs":{"url":"/docs/nexus/mensagens"}},{"name":"Webhooks","description":"Configuração e payloads assíncronos.","externalDocs":{"url":"/docs/nexus/webhooks"}}],"security":[{"NexusUserBearer":[]},{"InstanceApiKey":[]}],"components":{"securitySchemes":{"NexusUserBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT de usuário autenticado. O backend resolve tenant e role; nunca envie service role ou token administrativo."},"InstanceApiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Chave vinculada a uma instância, exibida somente na criação/rotação. Guarde fora do browser; uma rotação invalida imediatamente a chave anterior."}},"schemas":{"ChannelCapabilitiesResponse":{"type":"object","required":["registry"],"properties":{"registry":{"type":"object","required":["version","engines","multiplexAdapters"],"properties":{"version":{"type":"integer","minimum":1},"engines":{"type":"array","minItems":1,"maxItems":1,"items":{"$ref":"#/components/schemas/EngineCapabilityEntry"}},"multiplexAdapters":{"type":"array","maxItems":0,"items":{"type":"object","additionalProperties":false}}},"additionalProperties":false}},"additionalProperties":false},"CreateInstanceResponse":{"type":"object","required":["success","instanceId","transportType","status","message","sessionWasCleared"],"properties":{"success":{"type":"boolean","const":true},"instanceId":{"$ref":"#/components/schemas/InstanceId"},"phoneAlias":{"type":"string","maxLength":100},"transportType":{"$ref":"#/components/schemas/ConnectionType"},"status":{"type":"string","enum":["OFFLINE","RECONNECTING","ONLINE","disconnected"]},"message":{"type":"string"},"sessionWasCleared":{"type":"boolean"}},"additionalProperties":false},"CreateInstanceRequest":{"type":"object","required":["instanceId","transportType"],"properties":{"instanceId":{"$ref":"#/components/schemas/InstanceId"},"phoneAlias":{"type":"string","maxLength":100,"example":"Atendimento São Paulo"},"transportType":{"$ref":"#/components/schemas/ConnectionType"},"deviceType":{"type":"string","enum":["android","chrome","macos","edge","firefox","safari","opera"],"default":"android"}},"additionalProperties":false},"InstanceId":{"type":"string","pattern":"^[a-z0-9][a-z0-9-]{1,62}[a-z0-9]$","example":"atendimento-sp"},"InstanceStatusResponse":{"type":"object","required":["success","instanceId","status"],"properties":{"success":{"type":"boolean","const":true},"instanceId":{"$ref":"#/components/schemas/InstanceId"},"status":{"type":"string","enum":["OFFLINE","RECONNECTING","ONLINE"]},"connectedNumber":{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$"}},"additionalProperties":false},"InstanceCapabilitiesResponse":{"type":"object","required":["version","instance","capabilities"],"properties":{"version":{"type":"integer","const":1},"instance":{"type":"object","required":["id","engine","transport"],"properties":{"id":{"type":"string","format":"uuid"},"engine":{"type":["string","null"],"enum":["nexus",null]},"transport":{"type":"string","enum":["whatsapp_qr","conexao_oficial","conexao_hibrida","conexao_unificada","conexao_indisponivel"]}},"additionalProperties":false},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/InstanceCapability"}}},"additionalProperties":false},"SendMessageResponse":{"type":"object","required":["success","instanceId","type","jobId","status","idempotencyKey","reused"],"properties":{"success":{"type":"boolean","const":true},"message":{"type":"string"},"instanceId":{"$ref":"#/components/schemas/InstanceId"},"type":{"type":"string","const":"text"},"jobId":{"type":"string"},"status":{"type":"string"},"idempotencyKey":{"type":"string"},"reused":{"type":"boolean"}},"additionalProperties":false},"SendTextMessageRequest":{"type":"object","required":["instanceId","to","type","message"],"properties":{"instanceId":{"$ref":"#/components/schemas/InstanceId"},"to":{"type":"string","pattern":"^\\+[1-9][0-9]{7,14}$","example":"+5511999990000"},"type":{"type":"string","const":"text"},"message":{"type":"string","minLength":1}},"additionalProperties":false},"WebhookSettingsResponse":{"type":"object","required":["success","instance"],"properties":{"success":{"type":"boolean","const":true},"instance":{"type":"object","required":["instanceId","cfgWebhookEnabled","cfgWebhookEvents","cfgWebhookHasSecret"],"properties":{"instanceId":{"$ref":"#/components/schemas/InstanceId"},"cfgWebhookEnabled":{"type":"boolean"},"cfgWebhookUrl":{"type":["string","null"]},"cfgWebhookEvents":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventName"}},"cfgWebhookHasSecret":{"type":"boolean"},"cfgWebhookMirrorGhl":{"type":"boolean"}},"additionalProperties":true}},"additionalProperties":false},"WebhookSettingsRequest":{"type":"object","minProperties":1,"properties":{"cfgWebhookEnabled":{"type":"boolean"},"cfgWebhookUrl":{"type":"string","format":"uri","pattern":"^https://"},"cfgWebhookEvents":{"type":"array","minItems":1,"uniqueItems":true,"items":{"$ref":"#/components/schemas/WebhookEventName"}},"cfgWebhookSecret":{"type":"string","minLength":32,"writeOnly":true},"cfgWebhookMirrorGhl":{"type":"boolean","default":true}},"additionalProperties":false},"WebhookEvent":{"type":"object","required":["event","tenantId","instanceId","timestamp","data"],"properties":{"event":{"$ref":"#/components/schemas/WebhookEventName"},"tenantId":{"type":"string","format":"uuid"},"instanceId":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":true}},"additionalProperties":false},"EngineCapabilityEntry":{"type":"object","required":["id","label","channel","isDefault","capabilities"],"properties":{"id":{"type":"string","const":"nexus_qr"},"label":{"type":"string"},"channel":{"type":"string"},"isDefault":{"type":"boolean"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/CapabilityEntry"}}},"additionalProperties":false},"Error":{"type":"object","required":["error"],"properties":{"success":{"type":"boolean","const":false},"code":{"type":"string"},"error":{"type":"string"},"message":{"type":"string"},"correlationId":{"type":"string"}},"additionalProperties":true},"ConnectionType":{"type":"string","const":"whatsapp_qr"},"InstanceCapability":{"type":"object","required":["capability","engineStatus","available","reasonCode"],"properties":{"capability":{"type":"string"},"engineStatus":{"type":"string","enum":["supported","partial","missing","blocked"]},"available":{"type":"boolean"},"reasonCode":{"type":"string","enum":["READY","TRANSPORT_MIGRATING","TRANSPORT_MISMATCH","SESSION_DISCONNECTED","MESSAGING_NOT_READY","AUDIO_NOT_READY","VIDEO_NOT_READY","ENTITLEMENT_BLOCKED","QUOTA_BLOCKED","CONNECTION_UNAVAILABLE","CAPABILITY_NOT_IMPLEMENTED"]}},"additionalProperties":false},"WebhookEventName":{"type":"string","enum":["message_received","message_sent","instance_connected","instance_disconnected","qr_generated","message_failed"]},"CapabilityEntry":{"type":"object","required":["capability","status","dangerous"],"properties":{"capability":{"type":"string","const":"outbound_text"},"status":{"type":"string","const":"supported"},"dangerous":{"type":"boolean","const":false}},"additionalProperties":false}},"responses":{"BadRequest":{"description":"Requisição inválida.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"Credencial ausente, inválida ou expirada.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"Credencial válida sem permissão, tenant ou entitlement.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Recurso não encontrado no tenant autenticado.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Conflict":{"description":"Estado ou chave natural conflita com um recurso existente.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"InternalError":{"description":"Falha interna ou indisponibilidade temporária da conexão.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"description":"Identificador único da intenção. Reutilize somente ao repetir a mesma operação após timeout.","schema":{"type":"string","minLength":16,"maxLength":128}},"WebhookSignature":{"name":"X-Nexus-Signature","in":"header","required":false,"description":"HMAC SHA-256 no formato sha256=<hex>, calculado sobre o corpo bruto quando um segredo está configurado.","schema":{"type":"string","pattern":"^sha256=[a-f0-9]{64}$"}}}}}