Pular para o conteúdo
ampli prescreve
Guia de integração V2 Nova versão

Prescrição embarcada por bundleJS

Autentique o parceiro, crie a sessão de prescrição e incorpore o bundle na sua aplicação.

https://devprescription.amplimed.cloud/identity/v1 contrato v1 ambiente de desenvolvimento
Baixar .md

O manual inteiro — narrativa, contrato e exemplos — em um arquivo Markdown, para colar no assistente de IA que você usa e pedir o código na sua linguagem.

1

Autentique o parceiro #

POST https://devprescription.amplimed.cloud/identity/v1 /partners/authenticate

Troque clientId e secretKey por um token de curta duração.

A integração começa trocando as credenciais do parceiro por um token de curta duração. A API confere o clientId e compara a secretKey com o hash guardado no cadastro do parceiro. Esse token existe por um único motivo: autorizar a criação da sessão de prescrição na etapa seguinte. Ele não dá acesso a dado de paciente nem é o token que o front embarcado usa.

Esta chamada é server-to-server

A secretKey nunca pode sair do backend do parceiro. Não a coloque em JavaScript, em aplicativo mobile, em variável exposta ao browser nem em repositório — quem tem a secretKey consegue abrir sessões em nome do seu serviço.

Onde guardar as credenciais

Em variável de ambiente ou em um gerenciador de segredos (AWS Secrets Manager, Vault, o que já existir na sua stack). Em Laravel, isso significa .env lido por config() — nunca o valor escrito direto no código. O .env não vai para o versionamento.

O que fazer quando vier 401

Um 401 significa que a credencial não confere — e repetir a chamada não vai mudar isso. Não coloque retry automático em loop aqui. Confira, nesta ordem: se você está apontando para o ambiente certo, se o clientId é o do ambiente em questão, e se a secretKey não foi rotacionada. Retry com backoff faz sentido para 5xx e timeout, não para 401.

Rotação da secretKey

A secretKey pode ser trocada a qualquer momento a pedido do parceiro, e deve ser trocada imediatamente se houver suspeita de vazamento. Como ela é lida do ambiente, a rotação é: gerar a nova credencial com o time da Amplimed, atualizar o segredo no seu ambiente e reiniciar a aplicação. Tokens já emitidos continuam válidos até expirar, então a troca não derruba sessões em andamento.

Cache do token

O token é de curta duração. Guardá-lo em memória ou em cache pelo tempo de vida informado em expiresIn evita uma chamada de autenticação a cada sessão criada. Sempre respeite o expiresAt devolvido em vez de assumir um prazo fixo.

Corpo da requisição

Campo Tipo Detalhes
clientId string
obrigatório
secretKey string
obrigatório

Resposta 200

`PartnerTokenResource`

Campo Tipo Detalhes
token string
obrigatório
tokenType string
obrigatório Bearer
expiresIn string
obrigatório
expiresAt string
obrigatório

Erros

401 clientId ou secretKey inválidos.
Exemplo
{
    "error_code": "INVALID_PARTNER_CREDENTIALS",
    "message": "Invalid partner credentials."
}
422 Validation error
Exemplo
{
    "message": "<string>",
    "errors": []
}
curl -X POST 'https://devprescription.amplimed.cloud/identity/v1/partners/authenticate' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"clientId":"SEU_CLIENT_ID","secretKey":"SUA_SECRET_KEY"}'
Resposta 200
{
    "token": "eyJhbGciOiJIUzI1NiJ9.TOKEN_DE_PARCEIRO.ASSINATURA",
    "tokenType": "Bearer",
    "expiresIn": "300",
    "expiresAt": "2026-01-01T00:05:00Z"
}

Testar

Aponta para o ambiente de desenvolvimento. Não use credenciais de produção aqui.

Próximo passo: Crie a sessão de prescrição
2

Crie a sessão de prescrição #

POST https://devprescription.amplimed.cloud/identity/v1 /sessions

Envie profissional e paciente e receba o embeddedToken.

Com o token de parceiro em mãos, você cria a sessão de prescrição. A API resolve o escopo de módulos, valida os customFields contra o schema acordado no seu cadastro, grava um snapshot do contexto (parceiro, profissional, paciente) e devolve o embeddedToken.

Token de parceiro e embeddedToken são coisas diferentes

Esta é de longe a maior fonte de confusão de quem integra pela primeira vez:

  • O token de parceiro (etapa 1) identifica a sua empresa. Ele vive no seu backend, autoriza a criação de sessões e não deve chegar ao browser.
  • O embeddedToken (esta etapa) identifica uma sessão específica — este profissional, este paciente, estes escopos, este prazo. É ele, e apenas ele, que vai para o bundle embarcado no front.

Mandar o token de parceiro para o front é um erro de segurança; mandar o embeddedToken para POST /sessions simplesmente não funciona.

Como os scopes são resolvidos

Os módulos liberados na sessão são o cruzamento de duas listas: o piso regulatório do conselho do profissional (o que aquele conselho permite prescrever) e o teto comercial do parceiro (o que a sua empresa contratou). A sessão recebe a interseção.

Na prática: se o seu contrato inclui um módulo que o conselho daquele profissional não autoriza, ele não aparece nos scopes. E se o profissional poderia prescrever algo que a sua empresa não contratou, também não aparece. Por isso o register.type é obrigatório — é ele que determina o piso. Leia sempre os scopes devolvidos em vez de assumir o que foi contratado.

customFields

Os customFields precisam bater com o customFieldsSchema definido no cadastro do seu parceiro. Campo fora do schema combinado faz a chamada voltar 422. Se você precisa de um campo novo, ele é acordado no cadastro primeiro — não basta começar a enviá-lo.

professionalId e patientId

São identificadores da Amplimed, não do seu sistema. Envie o id quando o profissional ou o paciente já existir no nosso cadastro. Se ainda não existir, mande null — o contrato aceita null nos dois, e nesse caso quem identifica a pessoa é o resto do payload: nome, documento e, no profissional, o registro do conselho.

Ciclo de vida da sessão

A sessão nasce em createdAt e vale até expiresAt, conforme o TTL configurado para o parceiro. Enquanto o profissional estiver trabalhando, a renovação desliza esse prazo e devolve um embeddedToken novo. Quando o atendimento termina, encerre a sessão em vez de deixá-la expirar sozinha — assim ela deixa de ser utilizável imediatamente. Uma sessão por atendimento: não reaproveite a mesma sessão para outro paciente.

LGPD: dado de paciente trafega aqui

Este payload carrega nome, documento, data de nascimento, contato e endereço do paciente. Não registre o corpo cru desta requisição em log, APM, ferramenta de erro ou histórico de requisições. Se precisar de rastreio, registre apenas identificadores (sessionId, patientId) e o status da resposta.

Requer o token de parceiro

Envie o token da etapa 1 no header Authorization: Bearer <token>.

Corpo da requisição

Campo Tipo Detalhes
professional object
obrigatório
professional.professionalId string
opcional nullable
professional.name string
obrigatório
professional.register object
obrigatório
professional.register.type string
obrigatório
professional.register.value string
obrigatório
professional.register.state string
obrigatório
professional.specialty string
opcional nullable
professional.document object
obrigatório
professional.document.type string
obrigatório
professional.document.value string
obrigatório
patient object
obrigatório
patient.patientId string
opcional nullable
patient.name string
obrigatório
patient.document object
obrigatório
patient.document.type string
obrigatório cpf passport rg
patient.document.value string
obrigatório
patient.birthDate string date-time
opcional nullable
patient.gender string
opcional nullable
patient.phone string
opcional nullable
patient.email string email
opcional nullable
patient.address object
opcional nullable
patient.address.street string
opcional
patient.address.number string
opcional
patient.address.complement string
opcional nullable
patient.address.neighborhood string
opcional
patient.address.city string
opcional
patient.address.state string
opcional
patient.address.zipCode string
opcional
patient.address.country string
opcional
customFields string[]
opcional nullable
embeddedType string
opcional nullable

Resposta 201

Sessão de prescrição criada.

Campo Tipo Detalhes
sessionId string
obrigatório
embeddedToken string
obrigatório nullable
embeddedType string
obrigatório nullable
status string
obrigatório nullable
apiVersion string
obrigatório nullable
scopes string
obrigatório nullable
featureFlags string
obrigatório nullable
createdAt string
obrigatório
expiresAt string
obrigatório

Erros

422 customFields fora do customFieldsSchema do parceiro, ou payload inválido.
Exemplo
{
    "message": "<string>",
    "errors": []
}
curl -X POST 'https://devprescription.amplimed.cloud/identity/v1/sessions' \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer SEU_TOKEN_DE_PARCEIRO' \
  -H 'Content-Type: application/json' \
  -d '{"professional":{"professionalId":null,"name":"Dra. Ana Souza","register":{"type":"CRM","value":"123456","state":"SC"},"specialty":"Clínica Médica","document":{"type":"cpf","value":"00000000000"}},"patient":{"patientId":null,"name":"João da Silva","document":{"type":"cpf","value":"11111111111"},"birthDate":"1985-04-12T00:00:00Z","gender":"male","phone":"+5548999999999","email":"joao@exemplo.com","address":{"street":"Rua das Flores","number":"100","complement":null,"neighborhood":"Centro","city":"Florianópolis","state":"SC","zipCode":"88010000","country":"BR"}},"customFields":[],"embeddedType":null}'
Resposta 201
{
    "sessionId": "65f0c3a1d4e5b6a7c8d9e0f1",
    "embeddedToken": "eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA",
    "embeddedType": null,
    "status": "active",
    "apiVersion": "v1",
    "scopes": "<string>",
    "featureFlags": "<string>",
    "createdAt": "2026-01-01T00:00:00Z",
    "expiresAt": "2026-01-01T00:05:00Z"
}

Testar

Aponta para o ambiente de desenvolvimento. Não use credenciais de produção aqui.

Sem token ativo — rode a etapa 1

professional

professional.register

professional.document

patient

patient.document

patient.address

Próximo passo: Incorpore o bundle
3

Incorpore o bundle #

front-end

Carregue o bundle e inicialize com o embeddedToken.

A prescrição V2 roda como um bundle JavaScript montado dentro de um elemento da sua página — não é iframe. Você carrega o script, cria um elemento host e chama Ampliprescreve.init() passando o embeddedToken da sessão criada na etapa anterior.

Só o embeddedToken vai para o front

O sessionToken que o bundle recebe é o embeddedToken devolvido por POST /sessions — nunca o token de parceiro da etapa 1. O token de parceiro autoriza criar sessões em nome da sua empresa: se ele chegar ao browser, qualquer pessoa com acesso à página pode abrir sessões para qualquer paciente.

Como importar o bundle

O script é servido pela Amplimed e a URL varia por ambiente — trate-a como configuração, não como constante no código. Neste ambiente ela é https://devprescription.amplimed.cloud/bundle/ampliprescreve.umd.js.

Em página tradicional, uma <script> no HTML resolve. Em SPA, você pode deixá-la no index.html ou carregá-la sob demanda, só quando a prescrição for aberta — é o que os exemplos de React e Vue fazem, guardando a promessa do carregamento para o script não entrar na página mais de uma vez.

shadow e tema

Com shadow: true o bundle monta dentro de um shadow DOM, isolando o CSS da prescrição do CSS da sua aplicação — é o recomendado, porque evita que o seu reset ou framework de estilo vaze para dentro da prescrição. O theme aceita colorPrimary e radius para a prescrição acompanhar a identidade visual do parceiro.

Reabrir a prescrição exige um host novo

attachShadow só pode ser chamado uma vez por elemento. Se você inicializar o bundle no mesmo elemento de novo — ao reabrir a prescrição, por exemplo — a chamada falha porque já existe um shadow tree ali. Substitua o host por um clone vazio antes de reinicializar, como no exemplo ao lado.

Quando a sessão expira

O embeddedToken vale até o expiresAt da sessão. Se o atendimento for longo, renove a sessão pelo seu backend e reinicialize o bundle com o token novo — veja as operações opcionais.

<!-- Página tradicional: o bundle entra por script tag. -->
<div id="prescription-bundle"></div>

<script src="https://devprescription.amplimed.cloud/bundle/ampliprescreve.umd.js"></script>
<script>
  // O embeddedToken vem do seu backend, de POST /sessions.
  Ampliprescreve.init(document.getElementById('prescription-bundle'), {
    sessionToken: embeddedToken,
    shadow: true,
    theme: { colorPrimary: '#6366F1', radius: '8px' },
  });
</script>

Testar no navegador

Abre a prescrição de verdade, no ambiente de desenvolvimento, com o profissional e o paciente que você enviou na etapa 2.

Nenhuma sessão criada — rode a etapa 2

Operações opcionais #

Com as etapas acima a integração já funciona de ponta a ponta. As operações abaixo servem para manter a sessão viva além do prazo inicial e para encerrá-la explicitamente — use conforme a necessidade do seu fluxo.

Valide a sessão #

narrativa em revisão
GET https://devprescription.amplimed.cloud/identity/v1 /sessions/validate

Confirme que o embeddedToken ainda vale e recupere o contexto da sessão.

O contrato abaixo é gerado a partir do spec da API e já está correto. O texto explicativo desta etapa ainda está sendo escrito.

Corpo da requisição

Esta operação não recebe corpo.

Resposta 200

`SessionContextResource`

Campo Tipo Detalhes
sessionId string
obrigatório
embeddedToken string
obrigatório
partner object
obrigatório
professional object
obrigatório
patient object
obrigatório
scopes any[]
obrigatório
featureFlags any[]
obrigatório
customFields any[]
obrigatório
status string
obrigatório
apiVersion string
obrigatório
expiresAt string
obrigatório

Erros

404 Nenhuma sessão encontrada para o embeddedToken informado.
Exemplo
{
    "error_code": "SESSION_NOT_FOUND",
    "message": "Prescription session not found."
}
410 Sessão encontrada mas não está mais ativa (expirada ou encerrada).
Exemplo
{
    "error_code": "SESSION_EXPIRED",
    "message": "Prescription session is no longer active."
}
422 Validation error
Exemplo
{
    "message": "<string>",
    "errors": []
}
curl -X GET 'https://devprescription.amplimed.cloud/identity/v1/sessions/validate' \
  -H 'Accept: application/json'
Resposta 200
{
    "sessionId": "65f0c3a1d4e5b6a7c8d9e0f1",
    "embeddedToken": "eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA",
    "partner": [],
    "professional": [],
    "patient": [],
    "scopes": [],
    "featureFlags": [],
    "customFields": [],
    "status": "active",
    "apiVersion": "v1",
    "expiresAt": "2026-01-01T00:05:00Z"
}

Renove a sessão #

narrativa em revisão
POST https://devprescription.amplimed.cloud/identity/v1 /sessions/renew

Renovação deslizante do expiresAt, devolve um embeddedToken novo.

O contrato abaixo é gerado a partir do spec da API e já está correto. O texto explicativo desta etapa ainda está sendo escrito.

Corpo da requisição

Campo Tipo Detalhes
embeddedToken string
obrigatório

Resposta 200

`SessionContextResource`

Campo Tipo Detalhes
sessionId string
obrigatório
embeddedToken string
obrigatório
partner object
obrigatório
professional object
obrigatório
patient object
obrigatório
scopes any[]
obrigatório
featureFlags any[]
obrigatório
customFields any[]
obrigatório
status string
obrigatório
apiVersion string
obrigatório
expiresAt string
obrigatório

Erros

404 Nenhuma sessão encontrada para o embeddedToken informado.
Exemplo
{
    "error_code": "SESSION_NOT_FOUND",
    "message": "Prescription session not found."
}
410 Sessão encontrada mas não está mais ativa (expirada ou encerrada).
Exemplo
{
    "error_code": "SESSION_EXPIRED",
    "message": "Prescription session is no longer active."
}
422 Validation error
Exemplo
{
    "message": "<string>",
    "errors": []
}
curl -X POST 'https://devprescription.amplimed.cloud/identity/v1/sessions/renew' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"embeddedToken":"eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA"}'
Resposta 200
{
    "sessionId": "65f0c3a1d4e5b6a7c8d9e0f1",
    "embeddedToken": "eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA",
    "partner": [],
    "professional": [],
    "patient": [],
    "scopes": [],
    "featureFlags": [],
    "customFields": [],
    "status": "active",
    "apiVersion": "v1",
    "expiresAt": "2026-01-01T00:05:00Z"
}

Encerre a sessão #

narrativa em revisão
POST https://devprescription.amplimed.cloud/identity/v1 /sessions/end

Finaliza a sessão de prescrição antes do prazo de expiração.

O contrato abaixo é gerado a partir do spec da API e já está correto. O texto explicativo desta etapa ainda está sendo escrito.

Corpo da requisição

Campo Tipo Detalhes
embeddedToken string
obrigatório

Resposta 200

`SessionContextResource`

Campo Tipo Detalhes
sessionId string
obrigatório
embeddedToken string
obrigatório
partner object
obrigatório
professional object
obrigatório
patient object
obrigatório
scopes any[]
obrigatório
featureFlags any[]
obrigatório
customFields any[]
obrigatório
status string
obrigatório
apiVersion string
obrigatório
expiresAt string
obrigatório

Erros

404 Nenhuma sessão encontrada para o embeddedToken informado.
Exemplo
{
    "error_code": "SESSION_NOT_FOUND",
    "message": "Prescription session not found."
}
410 Sessão encontrada mas não está mais ativa (expirada ou encerrada).
Exemplo
{
    "error_code": "SESSION_EXPIRED",
    "message": "Prescription session is no longer active."
}
422 Validation error
Exemplo
{
    "message": "<string>",
    "errors": []
}
curl -X POST 'https://devprescription.amplimed.cloud/identity/v1/sessions/end' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{"embeddedToken":"eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA"}'
Resposta 200
{
    "sessionId": "65f0c3a1d4e5b6a7c8d9e0f1",
    "embeddedToken": "eyJhbGciOiJIUzI1NiJ9.TOKEN_DA_SESSAO.ASSINATURA",
    "partner": [],
    "professional": [],
    "patient": [],
    "scopes": [],
    "featureFlags": [],
    "customFields": [],
    "status": "active",
    "apiVersion": "v1",
    "expiresAt": "2026-01-01T00:05:00Z"
}

Exemplo de ponta a ponta #

As duas etapas juntas: o backend do parceiro autentica, recebe o token de parceiro e o usa imediatamente para criar a sessão. É nesta ligação que a maioria das integrações erra.

# 1. Autentique o parceiro e guarde o token.
#    As credenciais vêm do ambiente, nunca do código versionado.
TOKEN=$(curl -s -X POST 'https://devprescription.amplimed.cloud/identity/v1/partners/authenticate' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d "{\"clientId\": \"$PARTNER_CLIENT_ID\", \"secretKey\": \"$PARTNER_SECRET_KEY\"}" \
  | jq -r '.token')

# 2. Crie a sessão com esse token.
curl -X POST 'https://devprescription.amplimed.cloud/identity/v1/sessions' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"professional":{"professionalId":null,"name":"Dra. Ana Souza","register":{"type":"CRM","value":"123456","state":"SC"},"specialty":"Clínica Médica","document":{"type":"cpf","value":"00000000000"}},"patient":{"patientId":null,"name":"João da Silva","document":{"type":"cpf","value":"11111111111"},"birthDate":"1985-04-12T00:00:00Z","gender":"male","phone":"+5548999999999","email":"joao@exemplo.com","address":{"street":"Rua das Flores","number":"100","complement":null,"neighborhood":"Centro","city":"Florianópolis","state":"SC","zipCode":"88010000","country":"BR"}},"customFields":[],"embeddedType":null}'

Próximos passos