Os plug-ins de conversão para reservas em restaurantes no ChatGPT estão em versão beta e em testes com parceiros aprovados. Para solicitar acesso, preencha este formulário
aqui
Objetivo
Nosso objetivo é permitir que o ChatGPT invoque diretamente plug-ins de parceiros em casos de uso com forte intenção de realizar uma ação, como reservas em restaurantes.
Depois que os parceiros nos fornecerem um feed para pesquisa, poderemos conectar seus servidores MCP para ações de conversão no fundo do funil. Para isso, os plug-ins dos parceiros devem seguir um contrato padronizado para o nome do widget, o nome da ferramenta e os dados de entrada da ferramenta.
Se você quer criar um plug-in que siga esta especificação, solicite acesso pelo formulário para comerciantes do ChatGPT.
Experiência do usuário
Quando os usuários pesquisam restaurantes próximos, o cartão do restaurante e a barra lateral incluem um botão Reservar que pode abrir a interface do provedor de reservas do restaurante.
Botão Reservar na interface do restaurante:

Modal de reserva aberto por esse botão:

Contrato obrigatório (atualmente)
Para a integração atual de reservas, apenas os itens a seguir são obrigatórios:
- Nome do widget:
ui://widget/restaurant-reservation.html - Nome da ferramenta:
restaurant_reservation
restaurant_reservation deve definir:
_meta.ui.resourceUri = "ui://widget/restaurant-reservation.html";
Toda ferramenta chamada diretamente de um widget deve definir:
_meta["openai/widgetAccessible"] = true;
Dados de entrada de restaurant_reservation
Payload mínimo (sempre enviado):
{
"restaurant_id": "string"
}
Também podemos enviar o payload abaixo. Você pode usá-lo para renderização otimista no modal (por exemplo, para evitar esqueletos de interface ou estados de carregamento durante a hidratação dos dados):
{
"restaurant_name": "string",
"restaurant_image": "string",
"restaurant_address": {
"address": "string",
"city": "string",
"state": "string",
"zipcode": "string",
"country": "string"
}
}
Requisito de feed (integração com a pesquisa)
Para habilitar o roteamento do botão Reservar, ingerimos um feed de estabelecimentos fornecido pelos parceiros.
Objetivo e escopo
Este contrato de feed define:
- Os dados mínimos dos estabelecimentos necessários para correspondência e classificação.
- Uma API de listagem paginada.
- A detecção de alterações para evitar buscas completas desnecessárias.
Registro do estabelecimento (campos mínimos obrigatórios)
Um objeto Business deve incluir:
id(string): estável e único no provedor.name(string)address(objectoustringformatada)location(objectcom latitude/longitude)phone_number(string, preferencialmente no formato E.164)website_url(string, URL)platform_url(string, URL da página canônica do estabelecimento na sua plataforma)
Estrutura mínima recomendada:
{
"id": "biz_123",
"name": "Acme Coffee",
"address": {
"line1": "123 Market St",
"line2": "Suite 5",
"locality": "San Francisco",
"region": "CA",
"postal_code": "94105",
"country": "US",
"formatted": "123 Market St, Suite 5, San Francisco, CA 94105, US"
},
"location": {
"latitude": 37.793,
"longitude": -122.396
},
"phone_number": "+14155551234",
"website_url": "https://acmecoffee.example",
"platform_url": "https://provider.example/biz/biz_123"
}
Se os componentes estruturados do endereço não estiverem disponíveis, address pode ser uma única
string formatada, mas ela deve ser consistente e legível para pessoas.
Endpoint de listagem paginada
Exemplo de endpoint:
GET /v1/businesses
Parâmetros de consulta:
- Paginação: use um único estilo
page+page_sizeoffset+limit- ou
next_page_token(token opaco; preferencial quando houver suporte) changes_token(string, opcional): indica se os dados mudaram desde o último ponto de verificação da sincronização.
A resposta deve incluir:
checksum(boolean): indica se houve alguma alteração desde ochanges_tokenfornecido (outruese nenhum tiver sido fornecido).businesses(Business[]): payload da página atual.- Metadados de paginação para o estilo selecionado:
page,page_size,total_pages(opcional), ouoffset,limit,total(opcional), ounext_page_token(string | null)
Exemplo de requisição e resposta
Requisição:
GET /v1/businesses?page=1&page_size=2&changes_token=sync_2026_03_10
Resposta:
{
"checksum": true,
"page": 1,
"page_size": 2,
"total_pages": 120,
"businesses": [
{
"id": "biz_123",
"name": "Acme Coffee",
"address": {
"line1": "123 Market St",
"locality": "San Francisco",
"region": "CA",
"postal_code": "94105",
"country": "US",
"formatted": "123 Market St, San Francisco, CA 94105, US"
},
"location": {
"latitude": 37.793,
"longitude": -122.396
},
"phone_number": "+14155551234",
"website_url": "https://acmecoffee.example",
"platform_url": "https://provider.example/biz/biz_123"
},
{
"id": "biz_124",
"name": "Golden Diner",
"address": "200 Howard St, San Francisco, CA 94105, US",
"location": {
"latitude": 37.789,
"longitude": -122.391
},
"phone_number": "+14155559876",
"website_url": "https://goldendiner.example",
"platform_url": "https://provider.example/biz/biz_124"
}
]
}
Como usamos este feed para pesquisa
Tratamos o feed de estabelecimentos como um índice de pesquisa. No momento da consulta, recuperamos candidatos por correspondência aproximada (nome + localização/endereço) e, em seguida, classificamos e removemos duplicatas com base na semelhança de nome/endereço, usando localização/telefone/URL como sinais adicionais.
Expansão recomendada (não obrigatória atualmente)
Para permitir a conclusão de todo o processo no chat, recomendamos adicionar:
refresh_availabilitymake_reservationreservation_confirmation