Introdução

A Partner API do Performance Hub permite que plataformas de parceiros externos se integrem de forma transparente aos módulos principais do Performance Hub. A API oferece suporte a visão computacional, análises, registro de acessos de membros e insights das instalações.

Formato das solicitações

A API aceita corpos de solicitação codificados em JSON e retorna respostas codificadas em JSON.

Limitação de taxa

Para garantir o uso justo e a estabilidade do sistema, as contas da Partner API começam com limites padrão:

  • 5 solicitações por segundo por endpoint
  • Recomendado: máximo de 1000 itens por solicitação em lote para um desempenho ideal
  • Máximo de 10MB de tamanho de payload

Os limites de taxa são ajustáveis e podem ser configurados caso a caso pelo seu gerente de conta de parceiro do Performance Hub. Se sua integração precisar de maior volume para o lançamento, migrações, preenchimentos retroativos de relatórios ou instalações de alto volume, informe isso durante a integração ou antes da janela de mudança planejada.

URL base

https://partner-api.performancehub.co/partner/v1/

Autenticação

O acesso à Partner API exige autenticação com chaves secretas de API. Gere e gerencie suas chaves no Partner Console.

As chaves de API são suas credenciais para acessar os recursos de parceiro. Cada chave tem acesso restrito a dados específicos da organização e pode ser desativada instantaneamente quando necessário.

Trate suas chaves de API com cuidado: elas dão acesso total à sua conta! Nunca exponha essas chaves em repositórios públicos, aplicativos do lado do cliente ou em qualquer lugar onde possam ser comprometidas.

Autentique as solicitações com HTTP Basic Auth, enviando sua chave de API como nome de usuário. Deixe a senha em branco.

A API aceita apenas conexões HTTPS seguras. Solicitações HTTP simples são rejeitadas, assim como quaisquer solicitações sem as credenciais de autenticação adequadas.

Exemplo de solicitação

curl https://partner-api.performancehub.co/partner/v1/organisations \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:
# The colon prevents curl from asking for a password.

Verificar a chave secreta

curl https://partner-api.performancehub.co/partner/v1/auth/ping \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:
# Returns { "message": "You are successfully authorised as <PartnerName>" }

Lista de verificação para entrada em produção

Use esta lista de verificação antes de ativar uma integração de parceiro para instalações em produção.

Configuração do Partner Console

  • Seu perfil de parceiro está completo.
  • A URL do seu logotipo, o site, a categoria e a descrição estão corretos.
  • Seu método de vinculação de dados está configurado: Direct Link ou Linking Identifier.
  • A vinculação de instalações foi testada com pelo menos uma instalação real.
  • O tipo de chave correto está sendo usado:
    • Dryrun para testes de gravação não destrutivos.
    • Read-only para consumo seguro de dados.
    • Live somente quando você estiver pronto para afetar os dados de produção.

Autenticação e gerenciamento de chaves

  • As chaves secretas são armazenadas somente no servidor.
  • As chaves não estão incorporadas em aplicativos do lado do cliente, aplicativos móveis, repositórios públicos ou tickets de suporte.
  • A rotação e a revogação de chaves foram testadas.
  • Sua equipe sabe qual chave é usada em cada ambiente.

Validação de dados

  • Os campos obrigatórios estão presentes em todos os endpoints que você chama.
  • Os identificadores de instalação correspondem ao método de vinculação configurado.
  • Os IDs do seu sistema são estáveis e não mudam entre sincronizações.
  • As importações grandes são divididas em lotes dentro dos limites documentados.
  • Os itens de lote com falha podem ser identificados e reenviados.

Teste de endpoints

Antes do lançamento, teste todos os endpoints dos quais sua integração depende:

  • É possível ler organizações e instalações.
  • É possível salvar e atualizar membros.
  • Planos de associação, zonas de acesso e horários de acesso são sincronizados corretamente.
  • Os check-ins são aceitos e podem ser correlacionados com o seu sistema.
  • Os snapshots de relatórios usam o período de relatório e as métricas esperados.
  • Os fluxos do Door/Gate Controller são testados em hardware real, quando aplicável.

Preparação para Access Time Windows

Se a integração fornecer Access Time Windows:

  • Os exemplos absolutos e semanais passam na lista de verificação de certificação do produtor.
  • As épocas são segundos Unix inteiros sem aspas; os limites exatos [from, to) foram testados.
  • Os padrões em UTC, os fusos horários IANA personalizados da integração e as transições de horário de verão relevantes foram verificados.
  • Um único fluxo de revisões de membro/origem, durável e monotônico, coordena as atualizações incrementais, a reconciliação e as novas tentativas.
  • Os operadores entendem o comportamento de omissão, substituição completa, idempotência, conflito, dados desatualizados e [] explícito.
  • Cada scope_key, incluindo default, tem um mapeamento aprovado no Performance Hub; foi testado que chaves desconhecidas falham de forma fechada.
  • A cadência de atualização esperada da integração, a idade máxima dos dados de origem, o comportamento com origem desatualizada e os alertas estão configurados.
  • Foi comprovado que uma falha na consulta à origem não emite um snapshot vazio ou parcial.
  • A convergência do fluxo em staging, o cancelamento/revogação e os limites de início/fim na porta física atendem às metas acordadas.
  • As regras regulares e as concessões permanentes foram verificadas como caminhos alternativos, e as janelas não podem contornar a desativação de usuários, blockAllAccess, a manutenção ou a geocerca.

Preparação para o controle de acesso

Para integrações de controle de acesso:

  • Seu sistema toma a decisão de acesso antes de chamar o Performance Hub.
  • A integração trata device_offline, maintenance_mode_active e unlock_confirmation_timeout.
  • Os operadores entendem que um tempo limite significa que o destravamento não foi confirmado.
  • Seus logs armazenam o event_id e o command_id retornados.
  • Você tem um processo manual alternativo para a equipe da instalação.

Tratamento de erros e novas tentativas

  • As respostas 400, 401, 403, 404, 409 e 422 são apresentadas aos operadores ou às equipes de suporte, em vez de serem repetidas cegamente.
  • As respostas 429, 500, 502, 503 e 504 usam uma lógica de novas tentativas limitada, com recuo.
  • Falhas repetidas geram um alerta no seu sistema.
  • A integração nunca descarta registros com falha silenciosamente.

Observabilidade

  • Seus logs incluem endpoint, carimbo de data/hora, identificador da instalação, ID do registro de origem, resultado da solicitação e corpo da resposta.
  • Sua equipe de suporte pode pesquisar por ID de membro, ID de instalação, ID de check-in ou ID de evento de destravamento.
  • Você tem uma forma de repetir ou reconciliar sincronizações com falha.

Lançamento em produção

  • O Performance Hub confirmou seu acesso de produção.
  • Pelo menos uma instalação em produção ativou sua integração.
  • Sua chave de produção está ativa.
  • Seus contatos operacionais e técnicos estão atualizados.
  • Seu processo de suporte está documentado para os clientes.

Depois que essas verificações forem concluídas, sua integração configurada aparecerá no diretório de parceiros do Performance Hub, dentro da plataforma principal do Performance Hub.

Práticas recomendadas

Use estes padrões para manter as integrações de parceiros previsíveis, observáveis e seguras para as instalações.

Identifique as instalações de forma consistente

Escolha o método de vinculação configurado para sua conta de parceiro e use-o de forma consistente:

  • Direct Link - use o facility_id do Performance Hub retornado pelo endpoint de instalações.
  • Linking Identifier - use seu próprio identificador de local, como um ID de filial, código de local ou número de loja.

Não envie os dois identificadores na mesma solicitação. O Performance Hub resolve as solicitações usando o método de vinculação configurado para sua conta de parceiro.

Consulte Métodos de vinculação de parceiros para obter orientações de configuração.

Faça gravações em lote com cuidado

A Partner API aceita corpos de solicitação JSON e foi projetada para fluxos de sincronização em lote, onde documentado. Mantenha os lotes limitados e passíveis de nova tentativa.

Orientações padrão:

  • Use até 1000 itens por solicitação em lote para um desempenho ideal.
  • Mantenha os payloads abaixo de 10MB.
  • Respeite o limite de 5 solicitações por segundo por endpoint.

Os limites de taxa são ajustáveis e podem ser configurados caso a caso pelo seu gerente de conta de parceiro do Performance Hub. Se você espera importações de alto volume, tráfego de lançamento ou preenchimentos retroativos de relatórios, combine o volume necessário antes da janela de mudança.

Se você precisar sincronizar um grande conjunto de dados, divida-o em blocos determinísticos e registre o ID de cada bloco do seu lado. Isso facilita a análise de novas tentativas com falha.

Tente novamente com segurança

Use recuo exponencial para falhas transitórias, como 429, 500, 502, 503 e 504.

Evite loops de repetição rápidos. Um bom ponto de partida é:

  1. Tentar novamente após 1 segundo.
  2. Tentar novamente após 2 segundos.
  3. Tentar novamente após 4 segundos.
  4. Parar e emitir um alerta se a operação ainda falhar.

Para falhas de validação, como 400 ou 422, corrija a solicitação antes de tentar novamente.

Use idempotência onde houver suporte

O endpoint de destravamento do Door/Gate Controller aceita um idempotency_key opcional. Reutilizar a mesma chave para o mesmo parceiro, instalação e porta retorna o resultado existente, quando houver um.

Use uma chave estável para a ação que está sendo realizada, por exemplo, um ID de check-in ou um ID de evento de acesso do seu sistema.

Não presuma que todos os endpoints de gravação oferecem suporte a idempotência, a menos que isso esteja documentado para o endpoint.

Mantenha os dados de origem limpos

Envie valores estáveis e normalizados sempre que possível:

  • Use IDs consistentes de membros, planos, instalações e check-ins do seu sistema de origem.
  • Use carimbos de data/hora ISO 8601 para datas e horários.
  • Envie números de telefone em formato internacional, quando disponíveis.
  • Envie moedas usando os campos documentados para cada endpoint.
  • Evite sobrecarregar campos de texto livre com dados que pertencem a campos estruturados.

Projete para sincronizações incrementais e completas

A maioria das integrações de parceiros precisa das duas:

  • Sincronizações incrementais para as mudanças do dia a dia.
  • Sincronizações completas de reconciliação para corrigir eventos perdidos, importações históricas ou divergências de dados.

Sua integração deve ser capaz de reenviar o estado atual de um membro, plano de associação ou snapshot de relatório sem depender do sucesso de uma solicitação anterior.

Publique Access Time Windows com segurança

Trate o valor access_time_windows de cada membro como um snapshot completo, com revisão independente:

  • Coordene um único fluxo monotonicamente crescente de access_time_windows_revision entre os workers incrementais e de reconciliação.
  • Repita uma entrega incerta ou transitória com a mesma revisão e o mesmo payload normalizado.
  • Omita access_time_windows quando não estiver atualizando esse valor.
  • Envie [] somente depois que uma consulta bem-sucedida à fonte oficial comprovar que não resta nenhuma janela. Nunca transforme um tempo limite, um resultado parcial ou uma falha de análise na origem em revogação.
  • Mantenha external_id e scope_key estáveis e certifique cada mapeamento de escopo antes da produção.
  • Monitore a idade dos dados de origem em relação à política de atualização acordada para essa integração.

Consulte o guia oficial para produtores de Access Time Windows para ver snapshots completos, fusos horários, horário de verão, cancelamento e vetores de teste.

Trate o controle de acesso como crítico para a segurança

Para destravamentos do Door/Gate Controller:

  • Seu sistema deve decidir se a pessoa tem permissão para entrar antes de chamar o Performance Hub.
  • O Performance Hub retorna 200 somente depois que o controlador local confirma que o relé foi fisicamente destravado.
  • A maioria das confirmações é concluída em 3-5 segundos.
  • Um tempo limite é uma falha explícita de destravamento, não um sucesso em segundo plano.
  • Tente novamente somente de acordo com as suas próprias regras de acesso e segurança.

Sempre registre o event_id e o command_id retornados pelo endpoint de destravamento.

Monitore sua integração

Use os logs de solicitações do Partner Console durante o desenvolvimento e o lançamento. Em produção, mantenha também seus próprios logs com:

  • Data e hora da solicitação.
  • Endpoint.
  • ID do registro de origem.
  • Identificador da instalação.
  • Código de status HTTP.
  • Corpo da resposta ou mensagem de erro do Performance Hub.

Esses campos tornam o suporte e a reconciliação muito mais rápidos quando um cliente pergunta o que aconteceu.

Organizações

Representa a entidade empresarial de nível mais alto que opera uma ou mais instalações integradas à plataforma Performance Hub.

Endpoints

GET /partner/v1/organisations - List all organisations

O objeto Organisation

Atributos

  • org_id string obrigatório

    Identificador exclusivo da organização.

  • name string obrigatório

    Nome da organização.

O objeto Organisation

{
  "org_id": "00000000-0000-0000-0000-000000000050",
  "name": "Harbourside Group"
}

Listar todas as organizações

Retorna uma lista das organizações acessíveis à sua conta de parceiro.

Retorno

Retorna um objeto JSON com uma propriedade data que contém uma matriz de objetos Organisation.

Solicitação

curl https://partner-api.performancehub.co/partner/v1/organisations \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Resposta

{
  "data": [
    {
      "org_id": "00000000-0000-0000-0000-000000000050",
      "name": "Harbourside Group"
    },
    {
      "org_id": "6ba7b811-9dad-11d1-80b4-00c04fd430c8",
      "name": "Wellness Studios Network"
    }
  ]
}

Instalações

Representa um local físico, como um escritório, uma loja, um estabelecimento, um campus, uma clínica ou uma academia, onde os membros podem acessar serviços.

Endpoints

GET /partner/v1/facilities - List all facilities

O objeto Facility (instalação)

Atributos

  • facility_id string obrigatório

    Identificador exclusivo da instalação.

  • org_id string obrigatório

    Identificador exclusivo da organização principal.

  • name string obrigatório

    Nome da instalação.

  • brand string opcional

    Nome da marca usada pela instalação.

  • website_url string opcional

    URL do site da instalação.

  • place_data object opcional

    Dados de localização da Google Places API, contendo país, endereço formatado, Google Place ID, estado/província e cidade.

  • social_links object opcional

    Links de redes sociais da instalação.

  • timezone string opcional

    Identificador de fuso horário IANA (por exemplo, "Australia/Sydney", "America/New_York").

O objeto Facility (instalação)

{
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "org_id": "00000000-0000-0000-0000-000000000050",
  "name": "Harbourside Central",
  "brand": "Harbourside",
  "website_url": "https://example.com/central",
  "social_links": {
    "instagram": {
      "handle": "@harbourside.central"
    },
    "facebook": {
      "handle": "HarboursideCentral"
    }
  },
  "place_data": {
    "country": {
      "iso_code": "AU",
      "full_name": "Australia"
    },
    "formatted_address": "123 Main Street, Suite 100, Sydney NSW 2000, Australia",
    "google_place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
    "province": {
      "abbreviation": "NSW",
      "full_name": "New South Wales"
    },
    "city": {
      "short_name": "Sydney",
      "full_name": "Sydney"
    }
  },
  "timezone": "Australia/Sydney"
}

Listar todas as instalações

Retorna uma lista das instalações acessíveis à sua conta de parceiro.

Retorno

Retorna um objeto JSON com uma propriedade data que contém uma matriz de objetos Facility.

Solicitação

curl https://partner-api.performancehub.co/partner/v1/facilities \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Resposta

{
  "data": [
    {
      "facility_id": "550e8400-e29b-41d4-a716-446655440000",
      "org_id": "00000000-0000-0000-0000-000000000050",
      "name": "Harbourside Central",
      "brand": "Harbourside",
      "website_url": "https://example.com/central",
      "place_data": {
        "country": {
          "iso_code": "AU",
          "full_name": "Australia"
        },
        "formatted_address": "123 Main Street, Sydney NSW 2000, Australia",
        "google_place_id": "ChIJN1t_tDeuEmsRUsoyG83frY4",
        "province": {
          "abbreviation": "NSW",
          "full_name": "New South Wales"
        },
        "city": {
          "short_name": "Sydney",
          "full_name": "Sydney"
        }
      },
      "timezone": "Australia/Sydney"
    }
  ]
}

Planos de associação

Define uma oferta que pode ser adquirida de uma organização ou instalação, incluindo serviços, direitos, programação e preços.

Endpoints

POST /partner/v1/membership-plans - Save a membership plan

O objeto Membership Plan

Atributos

  • membership_plan_id string obrigatório

    Identificador exclusivo do plano de associação.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador exclusivo da instalação no Performance Hub.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Valor do identificador exclusivo que o parceiro usa para cada local (por exemplo, "Branch ID", "Location Code", "Store Number"). Saiba mais

  • name string obrigatório

    Nome legível do plano (por exemplo, "Office tenant – business hours", "Student – term access", "Hotel guest", "10 Class Pack").

  • billing_cycle string opcional

    Frequência de cobrança. Um destes: weekly, fortnightly, monthly, annually ou one_time.

  • price integer opcional

    Custo base na menor unidade da moeda (centavos para USD/AUD).

  • currency string opcional

    Código de moeda ISO 4217 (por exemplo, "AUD", "USD").

  • description string opcional

    Descrição opcional de marketing ou interna.

  • active_members integer opcional

    Número de membros ativos que usam este plano de associação

  • is_recurring boolean opcional

    Indica se o plano é renovado automaticamente.

  • is_trial boolean opcional

    Indica se esta é uma oferta de avaliação.

  • visible_to_public boolean opcional

    Indica se o plano está disponível para compra por autoatendimento.

  • duration_days integer opcional

    Número de dias de validade do plano de associação.

  • access_zones array opcional

    Matriz das zonas de acesso incluídas no plano de associação. Cada zona pode definir os próprios horários de acesso. Consulte Zonas de acesso para obter detalhes.

  • class_limit integer opcional

    Número máximo de aulas permitidas (null para ilimitado).

O objeto Membership Plan

Este exemplo usa facility_id. Em uma integração com identificador de vinculação, envie "linking_identifier": "branch_downtown" em vez disso.

{
  "membership_plan_id": "plan_99999",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Office tenant – business hours",
  "description": "Weekday access to the level 3 tenancy and the end-of-trip facilities",
  "billing_cycle": "monthly",
  "price": 8900,
  "currency": "AUD",
  "duration_days": 30,
  "is_recurring": true,
  "is_trial": false,
  "visible_to_public": false,
  "active_members": 245,
  "access_zones": [
    {
      "name": "Level 3 Tenancy",
      "description": "Lift lobby, offices and meeting rooms on level 3",
      "access_hours": {
        "mon": [["07:00", "19:00"]],
        "tue": [["07:00", "19:00"]],
        "wed": [["07:00", "19:00"]],
        "thu": [["07:00", "19:00"]],
        "fri": [["07:00", "19:00"]]
      }
    },
    {
      "name": "End-of-trip Facilities",
      "description": "Bike storage, lockers and showers",
      "access_hours": {
        "mon": [["06:00", "20:00"]],
        "tue": [["06:00", "20:00"]],
        "wed": [["06:00", "20:00"]],
        "thu": [["06:00", "20:00"]],
        "fri": [["06:00", "20:00"]]
      }
    }
  ],
  "class_limit": null
}

Zonas de acesso

As zonas de acesso definem áreas específicas de uma instalação às quais um plano de associação concede acesso. Cada zona pode ter os próprios horários de acesso, permitindo restrições de horário diferentes por área.

Estrutura

Cada zona de acesso inclui:

  • name string obrigatório

    O nome da zona (por exemplo, "Level 3 Tenancy", "Library", "Guest Floors", "Main Gym Floor").

  • description string opcional

    Descrição do que está incluído nessa zona.

  • access_hours object opcional

    Horários de acesso específicos dessa zona. Consulte Horários de acesso para ver o formato dos intervalos de horário.

Exemplo

Um edifício de escritórios com uma academia para os locatários: acesso ao espaço locado durante o horário comercial e à academia do início da manhã até o fim da noite.

{
  "access_zones": [
    {
      "name": "Level 3 Tenancy",
      "description": "Lift lobby, offices and meeting rooms on level 3",
      "access_hours": {
        "mon": [["07:00", "19:00"]],
        "tue": [["07:00", "19:00"]],
        "wed": [["07:00", "19:00"]],
        "thu": [["07:00", "19:00"]],
        "fri": [["07:00", "19:00"]]
      }
    },
    {
      "name": "Tenant Gym",
      "description": "Ground-floor gym and change rooms for building tenants",
      "access_hours": {
        "mon": [["05:00", "22:00"]],
        "tue": [["05:00", "22:00"]],
        "wed": [["05:00", "22:00"]],
        "thu": [["05:00", "22:00"]],
        "fri": [["05:00", "22:00"]],
        "sat": [["07:00", "18:00"]],
        "sun": [["07:00", "18:00"]]
      }
    }
  ]
}

Horários de acesso

Os horários de acesso especificam quando os membros podem acessar uma zona específica em cada dia da semana. Os horários de acesso são definidos por zona de acesso, permitindo restrições de horário diferentes para áreas diferentes de uma instalação.

Estrutura

{
  "mon": [["start_time", "end_time"]],
  "tue": [["start_time", "end_time"]],
  "wed": [["start_time", "end_time"]],
  "thu": [["start_time", "end_time"]],
  "fri": [["start_time", "end_time"]],
  "sat": [["start_time", "end_time"]],
  "sun": [["start_time", "end_time"]]
}

Cada dia é uma matriz de intervalos de horário no formato HH:MM (relógio de 24 horas). Uma matriz vazia [] significa nenhum acesso naquele dia. Os dias omitidos são tratados da mesma forma que uma matriz vazia.

Exemplos de casos de uso

Locatário de escritório – horário comercial: acesso durante o horário comercial, somente em dias úteis.

{
  "access_hours": {
    "mon": [["07:00", "19:00"]],
    "tue": [["07:00", "19:00"]],
    "wed": [["07:00", "19:00"]],
    "thu": [["07:00", "19:00"]],
    "fri": [["07:00", "19:00"]]
  }
}

Estudante – acesso durante o período letivo: uma biblioteca de campus aberta em dias úteis, com uma pausa no meio do dia, e nas manhãs de sábado.

{
  "access_hours": {
    "mon": [["08:00", "12:30"], ["13:30", "21:00"]],
    "tue": [["08:00", "12:30"], ["13:30", "21:00"]],
    "wed": [["08:00", "12:30"], ["13:30", "21:00"]],
    "thu": [["08:00", "12:30"], ["13:30", "21:00"]],
    "fri": [["08:00", "12:30"], ["13:30", "17:00"]],
    "sat": [["09:00", "13:00"]]
  }
}

Academia – madrugador: acesso somente pela manhã em dias úteis.

{
  "access_hours": {
    "mon": [["04:00", "12:00"]],
    "tue": [["04:00", "12:00"]],
    "wed": [["04:00", "12:00"]],
    "thu": [["04:00", "12:00"]],
    "fri": [["04:00", "12:00"]]
  }
}

Hóspede de hotel – 24/7: acesso permanente, o caso de uso mais comum.

{
  "access_hours": {
    "mon": [["00:00", "23:59"]],
    "tue": [["00:00", "23:59"]],
    "wed": [["00:00", "23:59"]],
    "thu": [["00:00", "23:59"]],
    "fri": [["00:00", "23:59"]],
    "sat": [["00:00", "23:59"]],
    "sun": [["00:00", "23:59"]]
  }
}

Exemplo por zona

Um plano para hóspedes de hotel com acesso 24 horas aos andares de hóspedes e horários mais curtos para a piscina:

{
  "access_zones": [
    {
      "name": "Guest Floors",
      "description": "Lifts and corridors on the guest room levels",
      "access_hours": {
        "mon": [["00:00", "23:59"]],
        "tue": [["00:00", "23:59"]],
        "wed": [["00:00", "23:59"]],
        "thu": [["00:00", "23:59"]],
        "fri": [["00:00", "23:59"]],
        "sat": [["00:00", "23:59"]],
        "sun": [["00:00", "23:59"]]
      }
    },
    {
      "name": "Swimming Pool",
      "description": "Access to the swimming pool and change rooms",
      "access_hours": {
        "mon": [["06:00", "20:00"]],
        "tue": [["06:00", "20:00"]],
        "wed": [["06:00", "20:00"]],
        "thu": [["06:00", "20:00"]],
        "fri": [["06:00", "20:00"]],
        "sat": [["08:00", "18:00"]],
        "sun": [["08:00", "18:00"]]
      }
    }
  ]
}

Salvar um plano de associação

Cria ou atualiza registros de planos de associação. A API determina se deve criar ou atualizar com base no membership_plan_id.

Parâmetros

  • membership_plans array obrigatório

    Matriz de objetos Membership Plan a serem salvos. Máximo recomendado: 1000 itens por solicitação para um desempenho ideal. A API agrupa automaticamente os itens em lotes para processamento. Cada item deve incluir facility_id (obrigatório se linking_identifier não for usado) ou linking_identifier (obrigatório se facility_id não for usado).

Retorno

Retorna uma mensagem simples confirmando a operação de sincronização.

Solicitação

Este exemplo usa facility_id. Em uma integração com identificador de vinculação, envie "linking_identifier": "branch_downtown" em vez disso.

curl -X POST https://partner-api.performancehub.co/partner/v1/membership-plans \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "membership_plans": [
      {
        "membership_plan_id": "plan_99999",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Student – term access",
        "description": "Library and student hub access for one teaching term",
        "billing_cycle": "one_time",
        "price": 4500,
        "currency": "AUD",
        "duration_days": 84,
        "is_recurring": false,
        "is_trial": false,
        "visible_to_public": true,
        "active_members": 245,
        "access_zones": [
          {
            "name": "Library",
            "description": "Reading rooms, study spaces and bookable rooms",
            "access_hours": {
              "mon": [["08:00", "21:00"]],
              "tue": [["08:00", "21:00"]],
              "wed": [["08:00", "21:00"]],
              "thu": [["08:00", "21:00"]],
              "fri": [["08:00", "17:00"]],
              "sat": [["09:00", "13:00"]]
            }
          },
          {
            "name": "Student Hub",
            "description": "Common room, kitchen and lockers",
            "access_hours": {
              "mon": [["07:00", "22:00"]],
              "tue": [["07:00", "22:00"]],
              "wed": [["07:00", "22:00"]],
              "thu": [["07:00", "22:00"]],
              "fri": [["07:00", "22:00"]]
            }
          }
        ],
        "class_limit": null
      }
    ]
  }'

Resposta

Retorna uma mensagem de sucesso com metadados sobre a operação de sincronização.

{
  "message": "Membership plan sync successful.",
  "metadata": {
    "success": 98,
    "skipped": 2,
    "skipped_items": [
      {
        "membership_plan_id": "plan_456",
        "facility_id": null,
        "reason": "Missing facility_id"
      }
    ]
  }
}

Campos de metadados:

  • success - Número de planos de associação processados com sucesso
  • skipped - Número de planos ignorados (se houver)
  • skipped_items - Matriz dos planos ignorados, com os motivos (se houver)
  • dry-run - Sinalizador booleano ao usar o tipo de chave dryrun (se aplicável)

Membros

Representa um cliente individual de uma instalação. Pode ser um lead, um prospect, um cliente recorrente, um membro expirado ou um usuário bloqueado.

Os upserts de membros também podem incluir um snapshot access_time_windows completo e com revisão, contendo acessos absolutos e semanais recorrentes. Consulte Access Time Windows antes de produzir esses campos. Eles são permissões adicionais e não substituem as regras regulares nem as concessões permanentes da instalação.

Endpoints

POST /partner/v1/members - Save a member

O objeto Member

Atributos

  • member_id string obrigatório

    Identificador exclusivo do membro.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador exclusivo da instalação no Performance Hub.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Valor do identificador exclusivo que o parceiro usa para cada local (por exemplo, "Branch ID", "Location Code", "Store Number"). Saiba mais

  • first_name string obrigatório

    Nome do membro.

  • last_name string obrigatório

    Sobrenome do membro.

  • email string opcional

    Endereço de e-mail.

  • mobile_phone string opcional

    Número de celular no formato E.123 (por exemplo, "+1 415 555 2671").

  • address object opcional

    Objeto de endereço físico com as seguintes propriedades:

    • address_line_1 (string) - Endereço principal
    • address_line_2 (string, opcional) - Linha de endereço complementar
    • city (string) - Nome da cidade
    • state (string) - Código do estado/província
    • postal_code (string) - CEP/código postal
    • country (string) - Código de país ISO 3166-1 alfa-2 (por exemplo, "AU", "US")
    • country_name (string, opcional) - Nome completo do país
  • date_of_birth string opcional

    Data de nascimento no formato YYYY-MM-DD.

  • gender string opcional

    Um destes: male, female, non_binary, prefer_not_to_say ou unknown.

  • type string opcional

    Tipo de membro (por exemplo, staff, member, prospect).

  • tags array opcional

    Strings ou textos auxiliares rápidos para categorizar e identificar membros específicos (por exemplo, ["vip", "personal-training", "student"]).

  • membership_status string opcional

    Status atual da associação (por exemplo, active, expired, on_hold).

  • membership_plans array opcional

    Matriz de planos de associação vinculados ao membro.

  • profile_picture string opcional

    Foto de perfil codificada em Base64 (opcional).

  • created string opcional

    Carimbo de data/hora ISO 8601 de quando o membro foi criado.

  • updated string opcional

    Carimbo de data/hora ISO 8601 da última atualização do membro.

  • access_time_windows array opcional

    Snapshot completo, pertencente à origem, das Access Time Windows absolutas e/ou semanais recorrentes. Omita o campo para manter o snapshot inalterado; envie uma matriz vazia com uma revisão mais nova para revogá-lo. Consulte Access Time Windows para ver os formatos, a validação, o mapeamento de escopo e a semântica de substituição.

  • access_time_windows_revision integer obrigatório com access_time_windows

    Inteiro não negativo, monotonicamente crescente e seguro para JSON, para este fluxo de membro/origem. Obrigatório sempre que access_time_windows estiver presente.

O objeto Member

{
  "member_id": "member_11111",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "first_name": "John",
  "last_name": "Smith",
  "email": "john.smith@example.com",
  "mobile_phone": "+61 412 345 678",
  "date_of_birth": "1985-06-15",
  "gender": "male",
  "type": "member",
  "tags": ["vip", "personal-training"],
  "profile_picture": "/9j/4AAQSkZJRgABAQAAAQ...",
  "membership_status": "current",
  "created": "2024-01-15T10:30:00Z",
  "updated": "2024-01-20T14:45:00Z",
  "access_time_windows_revision": 1842,
  "access_time_windows": [
    {
      "external_id": "access-4b1782",
      "kind": "absolute",
      "from": 1792053000,
      "to": 1792058400,
      "timezone": "Australia/Perth",
      "scope_key": "after_hours_entry",
      "label": "Temporary site access"
    }
  ],
  "address": {
    "address_line_1": "456 Bourke Street",
    "address_line_2": "Apt 12",
    "city": "Melbourne",
    "state": "VIC",
    "postal_code": "3000",
    "country": "AU",
    "country_name": "Australia"
  },
  "membership_plans": [
    {
      "membership_plan_id": "plan_99999",
      "name": "Unlimited Monthly",
      "start_date": "2024-01-01T00:00:00Z",
      "status": "current",
      "is_current": true,
      "end_date": null
    }
  ]
}

Janelas de Tempo de Acesso

As Access Time Windows permitem que um membro de parceiro tenha acesso temporário ou recorrente fornecido por um sistema externo. Esta página é o guia oficial para produtores de access_time_windows e access_time_windows_revision.

As Access Time Windows são permissões adicionais que apenas concedem acesso. Uma janela ativa pode permitir o acesso, mas uma janela inativa, expirada, desatualizada ou não mapeada não nega um acesso que uma regra regular ou uma concessão permanente já permite. A desativação de usuários, o bloqueio explícito de portas, o modo de manutenção, a geocerca, os limites de taxa e a disponibilidade do controlador continuam valendo.

As implementações para sistemas de origem específicos são adaptadores separados. Elas devem converter os dados de origem para este contrato independente de fornecedor sem alterar o significado dos campos.

Campos do snapshot do membro

  • access_time_windows array opcional

    O snapshot completo de Access Time Windows deste membro e desta origem de parceiro. Um snapshot pode combinar janelas absolute e weekly. Omita o campo para manter o snapshot armazenado inalterado; envie [] para revogar todas as janelas pertencentes a essa origem.

  • access_time_windows_revision integer obrigatório com access_time_windows

    Um inteiro não negativo, monotonicamente crescente e seguro para JSON, para este fluxo de revisões de membro/origem. É obrigatório sempre que access_time_windows estiver presente e não pode exceder 9007199254740991.

Cada snapshot aceita no máximo 50 janelas. external_id, scope_key e label aceitam no máximo 120 caracteres. As janelas absolutas podem abranger no máximo 90 dias. Um dia semanal aceita no máximo oito blocos sem sobreposição. Dados inválidos são rejeitados, e não truncados ou presumidos.

Formatos de janela

Uma janela absoluta identifica um intervalo exato:

Solicitação combinada completa

Esta solicitação substitui o snapshot anterior do membro pertencente à origem por uma janela absoluta e uma janela semanal:

Regras de horário e limites

from, to, active_from e active_until são inteiros JSON em segundos Unix que identificam instantes em UTC:

  • Envie um inteiro JSON sem aspas. Strings numéricas, números de ponto flutuante, strings RFC 3339 e milissegundos Unix são rejeitados.
  • Todo intervalo é semiaberto: [from, to). O acesso pode começar exatamente em from e deixa de estar ativo exatamente em to.
  • from deve ser menor que to. Quando os dois limites semanais estiverem presentes, active_from deve ser menor que active_until.
  • Não derive épocas de uma data/hora local sem fuso horário. Primeiro, converta o horário de origem em um instante UTC, depois divida os milissegundos Unix por 1000 e verifique se o resultado é um inteiro.

Fusos horários e horário de verão

timezone deve ser um fuso horário IANA válido, como UTC, Australia/Perth ou America/New_York. O padrão é UTC quando omitido.

  • Janelas absolutas: from e to já identificam instantes UTC exatos. timezone é apenas um metadado de exibição e auditoria; alterá-lo nunca desloca nenhum dos instantes.
  • Janelas semanais: timezone define o horário local e as regras de horário de verão usadas para avaliar access_hours. Não converta previamente os blocos semanais para UTC.
  • Durante uma mudança em que o relógio é adiantado, um horário local que o fuso horário pula nunca ocorre.
  • Durante uma mudança em que o relógio é atrasado, os dois instantes reais com o horário local repetido correspondem ao bloco semanal.
  • active_from e active_until continuam sendo instantes UTC, mesmo quando uma janela semanal usa um fuso horário diferente de UTC.

access_hours usa sun a sat em minúsculas. Cada valor é uma matriz de pares [start, end] no formato HH:mm de 24 horas, com zeros à esquerda. Os blocos não podem ser vazios, devem estar ordenados e não podem se sobrepor. end é exclusivo. Um bloco não pode cruzar a meia-noite; divida um intervalo noturno de origem em um bloco no fim do primeiro dia e um bloco no início do dia seguinte.

IDs estáveis e mapeamento de escopo

external_id deve ser estável durante toda a vida de uma janela lógica e exclusivo dentro do snapshot do membro. Mantenha-o estável quando horários ou rótulos mudarem, para que os operadores e os registros de auditoria possam correlacionar as revisões. Não o reutilize para uma janela não relacionada.

scope_key é o seu destino lógico e estável de acesso. O padrão é default. Um administrador da instalação mapeia cada chave permitida para destinos do Performance Hub de toda a instalação, de portas ou de Escopo de acesso:

Snapshots completos e revisões

Trate os dois campos como uma partição com versionamento próprio dentro do upsert de membro:

Entrada Resultado
access_time_windows omitido O snapshot existente permanece inalterado; nenhuma revisão é necessária
Presente com uma revisão mais nova Todo o snapshot armazenado para este membro/origem é substituído
Mesma revisão e mesmo payload normalizado Repetição idempotente; o snapshot não muda
Mesma revisão e payload normalizado diferente Conflito; atribua uma nova revisão após a reconciliação
Revisão mais antiga O snapshot desatualizado é ignorado; ele não pode substituir um estado mais recente
access_time_windows: [] com uma revisão mais nova Revoga explicitamente todas as janelas pertencentes à origem

Um snapshot é completo, não um patch. Se a revisão 1842 tem as janelas A e B, a revisão 1843 contendo apenas B remove A.

Mantenha um único fluxo de revisões coordenado por parceiro/membro entre workers de webhook, polling, repetição e reconciliação completa. Uma sequência durável de banco de dados é preferível. Um valor em milissegundos Unix só pode ser usado como revisão quando todos os gravadores se coordenam e garantem ordenação e exclusividade estritas; ele é um valor de revisão, não um campo de época.

Mantenha a solicitação e a revisão exatas até que a resposta da API seja conhecida. Após um tempo limite ou erro transitório, repita o mesmo snapshot normalizado com a mesma revisão. Não atribua uma nova revisão apenas porque a entrega pelo transporte é incerta.

Cancelamento, expiração e falhas na origem

  • Cancelar uma janela: consulte com sucesso o estado oficial da origem, remova essa janela e envie o snapshot completo restante com uma revisão mais nova.
  • Cancelar todas as janelas: envie access_time_windows: [] com uma revisão mais nova.
  • Deixar uma janela absoluta expirar: ela deixa de permitir acesso em to; envie uma reconciliação posterior sem a entrada expirada para manter os snapshots limpos.
  • Encerrar uma janela semanal: remova-a em um snapshot mais novo ou use active_until quando a origem tiver um instante de término conhecido.
  • A consulta à origem falha ou está incompleta: não envie [] e não publique um snapshot parcial. Emita um alerta e repita a consulta. Transformar uma falha na origem em um snapshot vazio é uma revogação de acesso não intencional.
  • A solicitação à Partner API falha na validação: corrija os dados e envie uma revisão mais nova somente se o snapshot normalizado mudar. Repita falhas transitórias com a revisão original.

A atualização dos dados de origem é configurada por integração, com base na cadência de entrega e de reconciliação prometida. Antes da ativação, combine a idade máxima dos dados de origem, o que acontece quando ela é excedida, os limites de alerta e se os operadores podem aceitar depender apenas dos limites de cada janela. Uma janela de origem desatualizada nunca se torna uma regra de negação; as regras regulares e as concessões permanentes continuam sendo caminhos alternativos.

Algoritmo do produtor

Use este fluxo independente de linguagem em toda atualização de membro:

Lista de verificação de certificação

Conclua estas verificações em uma instalação de staging, usando o mapeamento final de scope_key:

  • Uma janela absoluta é aceita com o fuso horário omitido e é avaliada em UTC.
  • Uma janela absoluta com fuso horário IANA personalizado preserva os mesmos instantes from/to.
  • Uma janela semanal com fuso horário IANA personalizado segue o horário local nas transições de adiantamento e atraso do relógio.
  • Um snapshot combinado absoluto/semanal substitui completamente o snapshot anterior.
  • O acesso começa exatamente em from e termina exatamente em to; os fins dos blocos semanais também são exclusivos.
  • A atualização de horários sob o mesmo external_id com uma revisão mais nova entra em vigor.
  • Omitir access_time_windows altera outros campos do membro sem alterar as janelas.
  • Repetir a mesma revisão/payload é idempotente.
  • Mesma revisão/payload diferente retorna um conflito e não altera o snapshot.
  • Uma revisão mais antiga fora de ordem é relatada como desatualizada e não pode reverter o estado.
  • Um [] mais novo revoga as janelas pertencentes à origem; uma falha na consulta à origem não envia nada.
  • Um scope_key desconhecido ou não mapeado falha de forma fechada e gera um aviso visível para o operador.
  • Os alertas de idade dos dados de origem e a política configurada para origem desatualizada funcionam no limite acordado.
  • Os caminhos de webhook e de reconciliação completa convergem para o mesmo snapshot e a mesma ordem de revisões.
  • A entrega pelo fluxo chega ao Door & Gate Access dentro da meta acordada.
  • Uma janela ativa pode permitir a porta física mapeada, mas não pode contornar a desativação de usuários, blockAllAccess, a manutenção ou a geocerca.
  • Antes, fora e depois de uma janela, as regras regulares e as concessões permanentes continuam permitindo os usuários que se qualificam de outra forma.

Orientações relacionadas

{
  "external_id": "access-4b1782",
  "kind": "absolute",
  "from": 1792053000,
  "to": 1792058400,
  "timezone": "Australia/Perth",
  "scope_key": "after_hours_entry",
  "label": "Temporary site access"
}

Os campos obrigatórios são external_id, kind, from e to. timezone, scope_key e label são opcionais.

Uma janela semanal identifica intervalos recorrentes no horário local, opcionalmente limitados por instantes em UTC:

{
  "external_id": "weekly-early-access",
  "kind": "weekly",
  "timezone": "America/New_York",
  "access_hours": {
    "sun": [],
    "mon": [["06:00", "08:30"]],
    "tue": [["06:00", "08:30"]],
    "wed": [["06:00", "08:30"]],
    "thu": [["06:00", "08:30"]],
    "fri": [["06:00", "08:30"]],
    "sat": []
  },
  "active_from": 1790812800,
  "active_until": 1796083200,
  "scope_key": "main_entry",
  "label": "Weekday early access"
}

Os campos obrigatórios são external_id, kind e access_hours. timezone, active_from, active_until, scope_key e label são opcionais.

curl -X POST https://partner-api.performancehub.co/partner/v1/members \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      {
        "member_id": "member_11111",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        "first_name": "John",
        "last_name": "Smith",
        "access_time_windows_revision": 1842,
        "access_time_windows": [
          {
            "external_id": "access-4b1782",
            "kind": "absolute",
            "from": 1792053000,
            "to": 1792058400,
            "timezone": "Australia/Perth",
            "scope_key": "after_hours_entry",
            "label": "Temporary site access"
          },
          {
            "external_id": "weekly-early-access",
            "kind": "weekly",
            "timezone": "America/New_York",
            "access_hours": {
              "sun": [],
              "mon": [["06:00", "08:30"]],
              "tue": [["06:00", "08:30"]],
              "wed": [["06:00", "08:30"]],
              "thu": [["06:00", "08:30"]],
              "fri": [["06:00", "08:30"]],
              "sat": []
            },
            "active_from": 1790812800,
            "active_until": 1796083200,
            "scope_key": "main_entry",
            "label": "Weekday early access"
          }
        ]
      }
    ]
  }'

Use facility_id ou linking_identifier, de acordo com o método de vinculação configurado. Não envie os dois.

Conversão de época

2026-10-15T08:30:00Z é convertido em 1792053000:

UTC instant                 Unix milliseconds   Unix seconds sent
2026-10-15T08:30:00Z        1792053000000        1792053000

Conversão independente de linguagem:

instant = parse_source_timestamp_with_explicit_zone(source_timestamp)
milliseconds = instant.to_unix_milliseconds()
assert milliseconds modulo 1000 equals 0
seconds = milliseconds / 1000
assert seconds is a JSON-safe nonnegative integer

Se a origem tiver precisão inferior a um segundo, defina uma política deliberada de arredondamento de início/fim antes dos testes de integração. Nunca envie milissegundos esperando que a API deduza a unidade.

Partner scope_key           Performance Hub mapping
default                     Facility's configured default target
main_entry                  Access Scope "Main entrances"
after_hours_entry           Doors approved for after-hours entry

Os parceiros não enviam IDs de instalação, porta ou Escopo de acesso do Performance Hub dentro de uma janela. Um scope_key desconhecido, desativado ou não mapeado falha de forma fechada para essa janela; ele não amplia o acesso. Combine e teste os mapeamentos antes do lançamento.

function publish_member(member_key):
    source_result = fetch_authoritative_access_state(member_key)

    if source_result.failed or source_result.incomplete:
        record_failure(member_key)
        schedule_retry(member_key)
        return without sending access_time_windows

    windows = []
    for source_window in source_result.current_windows:
        if source_window.is_absolute:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "absolute",
                from: to_integer_unix_seconds(source_window.start_instant),
                to: to_integer_unix_seconds(source_window.end_instant),
                timezone: source_window.display_timezone or "UTC",
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })
        else:
            windows.append({
                external_id: stable_window_id(source_window),
                kind: "weekly",
                timezone: valid_iana_zone(source_window.timezone) or "UTC",
                access_hours: split_validate_and_sort_weekly_blocks(source_window),
                active_from: optional_integer_unix_seconds(source_window.active_start),
                active_until: optional_integer_unix_seconds(source_window.active_end),
                scope_key: stable_scope_key(source_window) or "default",
                label: safe_label(source_window)
            })

    normalized_snapshot = validate_sort_and_deduplicate(windows)
    revision = next_durable_member_revision(member_key)
    request = member_upsert_with(normalized_snapshot, revision)
    persist_for_retry(member_key, request)

    response = post_request(request)
    if response.is_transient_or_unknown:
        retry_exact_request_with_same_revision(request)
    else if response.is_revision_conflict:
        reconcile_with_latest_committed_source_state(member_key)
    else if response.is_stale_skip:
        stop_replaying_this_revision_and_reconcile(member_key)

Vetores de teste mínimos

[
  {
    "name": "absolute-half-open",
    "window": {
      "external_id": "tv-absolute",
      "kind": "absolute",
      "from": 1792053000,
      "to": 1792058400
    },
    "expect": {
      "1792052999": "inactive",
      "1792053000": "active",
      "1792058399": "active",
      "1792058400": "inactive"
    }
  },
  {
    "name": "weekly-dst",
    "window": {
      "external_id": "tv-weekly-dst",
      "kind": "weekly",
      "timezone": "America/New_York",
      "access_hours": {
        "sun": [["01:00", "03:30"]],
        "mon": [],
        "tue": [],
        "wed": [],
        "thu": [],
        "fri": [],
        "sat": []
      }
    },
    "expect": "Evaluate local wall time: skipped times do not occur; both repeated 01:30 instants qualify."
  }
]

Envie também vetores negativos para milissegundos Unix, strings numéricas, números de ponto flutuante, fusos IANA inválidos, from >= to, external_id duplicado, blocos sobrepostos, blocos noturnos, mais de oito blocos em um dia, mais de 50 janelas e chaves de escopo não mapeadas.

Salvar um membro

Cria ou atualiza registros de membros. A API determina se deve criar ou atualizar com base no member_id.

Parâmetros

  • members array obrigatório

    Matriz de objetos Member a serem salvos. Máximo recomendado: 1000 itens por solicitação para um desempenho ideal. A API agrupa automaticamente os itens em lotes para processamento. Cada item deve incluir facility_id (obrigatório se linking_identifier não for usado) ou linking_identifier (obrigatório se facility_id não for usado).

    Quando um membro inclui access_time_windows, ele também deve incluir access_time_windows_revision. A matriz é um snapshot completo da origem, não um patch. Omita-a para preservar o snapshot existente ou envie [] com uma revisão mais nova para revogar todas as janelas pertencentes à origem. Leia o guia de Access Time Windows antes de ativar este campo.

Retorno

Retorna uma mensagem simples confirmando a operação de sincronização.

Os campos do perfil do membro continuam sendo upserts normais, mesmo quando um snapshot de janelas é relatado como repetição idempotente ou como desatualizado e ignorado. Um snapshot conflitante, com a mesma revisão e payload diferente, não pode ser repetido sem alterações; reconcilie o estado da origem e envie uma revisão mais nova.

Solicitação

curl -X POST https://partner-api.performancehub.co/partner/v1/members \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "members": [
      {
        "member_id": "member_11111",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "first_name": "John",
        "last_name": "Smith",
        "email": "john.smith@example.com",
        "mobile_phone": "+61 412 345 678",
        "date_of_birth": "1985-06-15",
        "gender": "male",
        "type": "member",
        "tags": ["vip", "personal-training"],
        "profile_picture": "/9j/4AAQSkZJRgABAQAAAQ...",
        "membership_status": "current",
        "created": "2024-01-15T10:30:00Z",
        "updated": "2024-01-20T14:45:00Z",
        "access_time_windows_revision": 1842,
        "access_time_windows": [
          {
            "external_id": "access-4b1782",
            "kind": "absolute",
            "from": 1792053000,
            "to": 1792058400,
            "timezone": "Australia/Perth",
            "scope_key": "after_hours_entry",
            "label": "Temporary site access"
          }
        ],
        "address": {
          "address_line_1": "456 Bourke Street",
          "address_line_2": "Apt 12",
          "city": "Melbourne",
          "state": "VIC",
          "postal_code": "3000",
          "country": "AU",
          "country_name": "Australia"
        },
        "membership_plans": [
          {
            "membership_plan_id": "plan_99999",
            "name": "Unlimited Monthly",
            "start_date": "2024-01-01T00:00:00Z",
            "status": "current",
            "is_current": true,
            "end_date": null
          }
        ]
      }
    ]
  }'

Resposta

Retorna uma mensagem de sucesso com metadados sobre a operação de sincronização.

{
  "message": "Member sync successful.",
  "metadata": {
    "success": 245,
    "skipped": 5,
    "skipped_items": [
      {
        "member_id": "member_123",
        "facility_id": null,
        "reason": "Facility integration is disabled in facility-partner-config"
      }
    ]
  }
}

Campos de metadados:

  • success - Número de membros processados com sucesso
  • skipped - Número de membros ignorados (se houver)
  • skipped_items - Matriz dos membros ignorados, com os motivos (se houver)
  • dry-run - Sinalizador booleano ao usar o tipo de chave dryrun (se aplicável)

Check-ins

Representa o registro da presença de uma pessoa em uma instalação, aula ou atividade. Usado para acompanhar a frequência, analisar o uso e melhorar a precisão da detecção visual.

Endpoints

POST /partner/v1/check-ins - Save check-ins

O objeto Check-In

Atributos

  • check_in_id string opcional

    Identificador exclusivo do check-in. Opcional: gerado automaticamente a partir do par member_id e timestamp, se não for informado.

  • member_id string obrigatório

    Identificador exclusivo do membro.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador exclusivo da instalação no Performance Hub.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Valor do identificador exclusivo que o parceiro usa para cada local (por exemplo, "Branch ID", "Location Code", "Store Number"). Saiba mais

  • check_in_type string opcional

    Tipo de visita. Um destes: member, class, staff, guest ou trial.

  • source string opcional

    Como o check-in foi registrado. Os valores comuns incluem manual, tag, rfid, kiosk, app. Valores adicionais, como door_reader ou booking, também podem ser usados.

  • class_id string opcional

    Opcional. Se estiver vinculado a uma reserva ou frequência em aula.

  • timestamp string obrigatório

    Carimbo de data/hora no formato ISO 8601 de quando o check-in ocorreu.

O objeto Check-In

{
  // "check_in_id": "checkin_abc123",  // Optional - auto-generated from member_id + timestamp if not provided
  "member_id": "mem_12345",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "check_in_type": "member",
  "source": "rfid",
  "timestamp": "2025-01-20T08:45:30Z"
}

Salvar check-ins

Cria registros de check-in. A API elimina duplicatas automaticamente com base no membro, na instalação e no carimbo de data/hora.

Parâmetros

  • check_ins array obrigatório

    Matriz de objetos Check-In a serem salvos. Máximo recomendado: 1000 itens por solicitação para um desempenho ideal. A API agrupa automaticamente os itens em lotes para processamento. Cada item deve incluir facility_id (obrigatório se linking_identifier não for usado) ou linking_identifier (obrigatório se facility_id não for usado).

Retorno

Retorna uma mensagem simples confirmando a operação de sincronização.

Solicitação

curl -X POST https://partner-api.performancehub.co/partner/v1/check-ins \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "check_ins": [
      {
        // "check_in_id": "checkin_abc123",  // Optional - auto-generated from member_id + timestamp if not provided
        "member_id": "mem_12345",
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "check_in_type": "member",
        "source": "rfid",
        "timestamp": "2025-01-20T08:45:30Z"
      }
    ]
  }'

Resposta

Retorna uma mensagem de sucesso com metadados sobre a operação de sincronização.

{
  "message": "Check-in sync successful.",
  "metadata": {
    "success": 523,
    "skipped": 3,
    "skipped_items": [
      {
        "member_id": "member_789",
        "facility_id": null,
        "reason": "No matching facility_id for the linking_identifier"
      }
    ]
  }
}

Campos de metadados:

  • success - Número de check-ins processados com sucesso
  • skipped - Número de check-ins ignorados (se houver)
  • skipped_items - Matriz dos check-ins ignorados, com os motivos (se houver)
  • dry-run - Sinalizador booleano ao usar o tipo de chave dryrun (se aplicável)

Controle de acesso

A Partner API pode acionar o hardware Door/Gate Controller do Performance Hub nas instalações em que sua integração está ativada.

Use esta API quando o seu sistema de gestão de membros já tiver decidido que uma pessoa tem permissão para entrar. O Performance Hub não avalia o status da associação, os horários de acesso, as regras de zonas de portas, as verificações antifraude nem a lógica de suspensão. Seu sistema continua sendo a autoridade para essas decisões.

A solicitação de destravamento é síncrona. O Performance Hub envia o comando ao controlador local em tempo real e retorna 200 somente depois que o dispositivo confirma que o relé foi fisicamente destravado. A maioria das confirmações deve ser concluída em 3-5 segundos. Se nenhuma confirmação for recebida dentro do tempo limite, a API retorna uma falha explícita.

Você também pode registrar uma tentativa ou negação de acesso que nunca chegou ao controlador. Essa chamada não destrava a porta. Ela grava um evento nos Registros de acesso do Door & Gate Access.

Endpoints

GET /partner/v1/access-control/doors - List available Door/Gate Controllers
GET /partner/v1/access-control/doors/{door_id} - Get Door/Gate Controller status
POST /partner/v1/access-control/doors/{door_id}/unlock - Unlock a Door/Gate Controller
POST /partner/v1/access-control/doors/{door_id}/access-events - Record an access attempt or denial

O objeto Door/Gate Controller

Atributos

  • door_id string obrigatório

    Identificador exclusivo do Door/Gate Controller. Armazene-o no seu sistema após a descoberta e use-o ao chamar o endpoint de destravamento.

  • facility_id string obrigatório

    ID da instalação no Performance Hub.

  • linking_identifier string opcional

    Identificador da instalação no sistema do parceiro, quando sua integração usa identificadores de vinculação. Saiba mais

  • name string obrigatório

    Nome legível do dispositivo configurado no Performance Hub.

  • zone string opcional

    Zona ou local da porta, como Entrance.

  • status string obrigatório

    online ou offline.

  • relay_state string opcional

    Último estado conhecido do relé, como locked ou unlocked.

  • maintenance_mode string obrigatório

    Modo de manutenção atual. Um destes: off, force-open ou force-closed.

  • hold_time_seconds integer obrigatório

    Tempo padrão de abertura configurado para a porta.

  • last_seen string opcional

    Carimbo de data/hora ISO da atualização mais recente dos metadados do dispositivo.

O objeto Door/Gate Controller

{
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "linking_identifier": "branch_downtown",
  "name": "Front Door",
  "zone": "Entrance",
  "status": "online",
  "online": true,
  "relay_state": "locked",
  "maintenance_mode": "off",
  "hold_time_seconds": 10,
  "last_seen": "2026-05-01T04:30:00.000Z"
}

Listar Door/Gate Controllers

Retorna os Door/Gate Controllers disponíveis para sua integração.

Se nem facility_id nem linking_identifier forem informados, a API retorna os Door/Gate Controllers de todas as instalações vinculadas à sua conta de parceiro.

Recommended: Include a facility identifier whenever possible. Requests without `facility_id` or `linking_identifier` may take longer to load for partners with hundreds or thousands of Door/Gate Controllers.

Parâmetros

  • facility_id string opcional um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    ID da instalação no Performance Hub. Use-o em integrações de vinculação direta.

  • linking_identifier string opcional um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Seu próprio identificador de instalação/local. Use-o quando sua integração estiver configurada para identificadores de vinculação.

Retorno

Retorna uma matriz de objetos Door/Gate Controller.

Solicitação

curl -X GET "https://partner-api.performancehub.co/partner/v1/access-control/doors?facility_id=550e8400-e29b-41d4-a716-446655440000" \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Resposta

{
  "data": [
    {
      "door_id": "00000000000000000000000000000007",
      "facility_id": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Front Door",
      "zone": "Entrance",
      "status": "online",
      "relay_state": "locked",
      "maintenance_mode": "off",
      "hold_time_seconds": 10,
      "last_seen": "2026-05-01T04:30:00.000Z"
    }
  ]
}

Obter o status de um Door/Gate Controller

Recupera o último estado conhecido e a configuração básica de um único Door/Gate Controller.

Informe um identificador de instalação para que o Performance Hub possa verificar se a porta pertence a uma instalação que sua integração pode acessar.

Parâmetros

  • door_id string obrigatório

    ID do Door/Gate Controller retornado pelo endpoint de listagem.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    ID da instalação no Performance Hub. Obrigatório em integrações de vinculação direta.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador da instalação no sistema do parceiro. Obrigatório em integrações com identificador de vinculação.

Retorno

Retorna um objeto Door/Gate Controller.

Solicitação

curl -X GET "https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007?facility_id=550e8400-e29b-41d4-a716-446655440000" \
  -u sk_live_YOUR_PARTNER_SECRET_KEY:

Resposta

{
  "data": {
    "door_id": "00000000000000000000000000000007",
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Front Door",
    "zone": "Entrance",
    "status": "online",
    "relay_state": "locked",
    "maintenance_mode": "off",
    "hold_time_seconds": 10,
    "last_seen": "2026-05-01T04:30:00.000Z"
  }
}

Destravar um Door/Gate Controller

Envia um comando de destravamento ao Door/Gate Controller e aguarda a confirmação do relé físico de que ele foi destravado.

Seu sistema deve decidir se a pessoa está autorizada antes de chamar este endpoint. O Performance Hub verifica apenas a chave do parceiro, o acesso à instalação, a quem a porta pertence e o estado do dispositivo.

Parâmetros

  • door_id string obrigatório

    ID do Door/Gate Controller retornado pelo endpoint de listagem.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    ID da instalação no Performance Hub. Obrigatório em integrações de vinculação direta.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador da instalação no sistema do parceiro. Obrigatório em integrações com identificador de vinculação.

  • member_id string obrigatório

    ID do membro no sistema do parceiro. É usado para registros de auditoria e para a vinculação posterior de dados.

  • first_name string obrigatório

    Nome da pessoa que está abrindo a porta.

  • last_name string obrigatório

    Sobrenome da pessoa que está abrindo a porta.

  • full_name string opcional

    Opcional. Se omitido, o Performance Hub combina first_name e last_name.

  • check_in_id string opcional

    ID de check-in opcional do seu sistema, para correlação.

  • idempotency_key string opcional

    Chave opcional de proteção contra repetição. Reutilizar a mesma chave para o mesmo parceiro, instalação e porta retorna o resultado existente, quando disponível.

Retorno

Retorna 200 somente quando o dispositivo confirma que o relé foi fisicamente destravado. A porta usa o tempo de abertura configurado no Gerenciamento de dispositivos do Performance Hub; os parceiros não podem substituir o tempo do relé por solicitação. A maioria das confirmações deve ser concluída em 3-5 segundos. Trate o tempo limite documentado como uma falha explícita de destravamento e tente novamente somente de acordo com as suas próprias regras de segurança.

Falhas comuns:

  • 403 integration_not_enabled - sua integração não está ativada para a instalação.
  • 409 maintenance_mode_active - a equipe da instalação ativou o modo de manutenção para a porta.
  • 503 device_offline - o Door/Gate Controller está off-line ou desatualizado.
  • 504 unlock_confirmation_timeout - o comando foi enviado, mas nenhuma confirmação correspondente foi recebida antes do tempo limite.

Solicitação

curl -X POST https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007/unlock \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "member_id": "mem_12345",
    "first_name": "Jane",
    "last_name": "S.",
    "full_name": "Jane S.",
    "source": "door_reader",
    "idempotency_key": "unlock_20260501_0001"
  }'

Resposta

{
  "status": "unlocked",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "command_id": "00000000-0000-0000-0000-000000000049",
  "hold_time_seconds": 10,
  "confirmed_at": "2026-05-01T04:30:00.000Z"
}

Resposta de falha

{
  "status": "failed",
  "reason": "device_offline",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045"
}

Registrar uma tentativa ou negação de acesso

Registra uma tentativa ou negação de acesso que o seu sistema já decidiu. O Door/Gate Controller não é contatado e a porta não é destravada.

Use isto quando o seu sistema recusar a entrada ou quando uma tentativa precisar aparecer nos Registros de acesso do Door & Gate Access sem um destravamento. O Performance Hub não avalia o status da associação, os horários de acesso nem outras regras de acesso.

Um evento negado aparece nos Registros de acesso do Door & Gate Access com o resultado Denied, o nome do seu parceiro, a porta, o identificador do membro (quando você o envia) e o código do motivo em formato legível. Por exemplo, membership_expired é exibido como "Membership Expired". reason_display_text e user_email são armazenados com o evento.

Parâmetros

  • door_id string obrigatório

    ID do Door/Gate Controller retornado pelo endpoint de listagem.

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    ID da instalação no Performance Hub. Obrigatório em integrações de vinculação direta.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador da instalação no sistema do parceiro. Obrigatório em integrações com identificador de vinculação.

  • outcome string obrigatório

    denied ou attempted.

  • reason string opcional

    Código do motivo em snake_case minúsculo, com até 64 caracteres. Obrigatório quando outcome é denied. Exemplo: membership_expired.

  • reason_display_text string opcional

    Motivo legível, com até 256 caracteres. Exemplo: Membership expired on 2026-04-01.

  • member_id string opcional

    ID do membro no sistema do parceiro. Omita-o quando a credencial não corresponder a um membro, como no caso de um cartão desconhecido.

  • user_email string opcional

    E-mail da pessoa que tentou o acesso.

  • timestamp string opcional

    Quando a tentativa ocorreu, em ISO 8601 com fuso horário. Exemplo: 2026-05-18T10:15:30Z. O padrão é o horário em que a solicitação é recebida. Não pode estar mais de 5 minutos no futuro nem ser anterior a 30 dias.

  • idempotency_key string opcional

    Chave de proteção contra repetição, com até 128 caracteres. Reutilizar a mesma chave para o mesmo parceiro, instalação e porta retorna o resultado original.

Retorno

Retorna 201 quando o evento é registrado. Repetir o mesmo idempotency_key retorna 200 com idempotent definido como true e não cria outro evento.

Uma chave dry-run retorna 200 com dry_run definido como true. Nada é registrado.

Falhas comuns:

  • 400 - o corpo é inválido, uma negação não tem reason, o carimbo de data/hora está fora do intervalo ou facility_id / linking_identifier não corresponde a uma instalação vinculada.
  • 403 - a chave é somente leitura.
  • 403 integration_not_enabled - sua integração não está ativada para a instalação. message informa o motivo.
  • 404 - o Door/Gate Controller não foi encontrado para a instalação vinculada.

Solicitação

curl -X POST https://partner-api.performancehub.co/partner/v1/access-control/doors/00000000000000000000000000000007/access-events \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "facility_id": "550e8400-e29b-41d4-a716-446655440000",
    "outcome": "denied",
    "reason": "membership_expired",
    "reason_display_text": "Membership expired on 2026-04-01",
    "member_id": "mem_12345",
    "user_email": "member@example.com",
    "timestamp": "2026-05-18T10:15:30Z",
    "idempotency_key": "evt_abc12345"
  }'

Resposta

{
  "status": "recorded",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "outcome": "denied",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-05-18T10:15:30.000Z"
}

Repetição idempotente

{
  "status": "recorded",
  "event_id": "00000000-0000-0000-0000-000000000045",
  "outcome": "denied",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "timestamp": "2026-05-18T10:15:30.000Z",
  "idempotent": true
}

Relatórios das instalações

Um registro pontual que reúne as principais métricas operacionais e financeiras de uma instalação durante um período específico.

Endpoints

POST /partner/v1/report-snapshots - Save report snapshots

O objeto Report Snapshot

Atributos

  • facility_id string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Identificador exclusivo da instalação no Performance Hub.

  • linking_identifier string um ou outroInforme o tipo de identificador de instalação configurado para sua integração: use facility_id em integrações de vinculação direta ou linking_identifier em integrações com identificador de vinculação. Não envie os dois; a API usa o tipo de identificador configurado para sua conta de parceiro e ignora o outro. Saiba mais

    Valor do identificador exclusivo que o parceiro usa para cada local (por exemplo, "Branch ID", "Location Code", "Store Number"). Saiba mais

  • start_date string obrigatório

    Data de início do período do snapshot no formato YYYY-MM-DD.

  • end_date string obrigatório

    Data de término do período do snapshot no formato YYYY-MM-DD.

  • metrics object obrigatório

    Objeto de métricas que contém os dados de membros e de receita do período.

O objeto Report Snapshot

{
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  // "linking_identifier": "branch_downtown",  // If using linking identifier
  "start_date": "2025-01-01",
  "end_date": "2025-01-31",
  "metrics": {
    "members": {
      "active": 1200,
      "new": 45,
      "cancelled": 12
    },
    "revenue": {
      "total_payments": 289000.00,
      "total_payments_count": 1200,
      "currency": "AUD"
    }
  }
}

Salvar snapshots de relatórios

Envia métricas operacionais e financeiras de uma instalação durante um período específico.

Parâmetros

  • snapshots array obrigatório

    Matriz de objetos Report Snapshot a serem salvos. Máximo de 25 itens por solicitação. Cada item deve incluir facility_id (obrigatório se linking_identifier não for usado) ou linking_identifier (obrigatório se facility_id não for usado).

Retorno

Retorna uma mensagem simples confirmando a operação de sincronização.

Solicitação

curl -X POST https://partner-api.performancehub.co/partner/v1/report-snapshots \
  -u sk_live_YOUR_PARTNER_SECRET_KEY: \
  -H "Content-Type: application/json" \
  -d '{
    "snapshots": [
      {
        "facility_id": "550e8400-e29b-41d4-a716-446655440000",
        // "linking_identifier": "branch_downtown",  // If using linking identifier
        "start_date": "2025-01-01",
        "end_date": "2025-01-31",
        "metrics": {
          "members": {
            "active": 1200,
            "new": 45,
            "cancelled": 12
          },
          "revenue": {
            "total_payments": 289000.00,
            "currency": "AUD"
          }
        }
      }
    ]
  }'

Resposta

{
  "message": "Report snapshot sync successful."
}

Erros

A Partner API usa códigos de status HTTP padrão e corpos de resposta JSON para explicar por que uma solicitação falhou.

Formato da resposta de erro

A maioria dos erros da API retorna um corpo JSON com uma mensagem e, quando disponíveis, detalhes estruturados.

Códigos de status

Falhas de Access Time Windows

A validação das janelas falha antes que o snapshot inválido seja gravado. As causas comuns que não devem ser repetidas incluem:

  • Ausência de access_time_windows_revision quando access_time_windows está presente.
  • Valores de época em string, em ponto flutuante ou provavelmente em milissegundos.
  • Um fuso horário IANA inválido, um intervalo invertido, um external_id duplicado, blocos semanais sobrepostos ou um bloco noturno que não foi dividido.
  • Um valor fora dos limites documentados de quantidade, tamanho ou duração.

Uma revisão repetida com conteúdo normalizado diferente é um 409 Conflict. Faça a reconciliação com o estado oficial mais recente e atribua uma revisão mais nova; não continue repetindo o par conflitante. Uma revisão mais antiga é relatada como um snapshot desatualizado ignorado, em vez de poder substituir um estado mais recente. Um scope_key desconhecido ou não mapeado falha de forma fechada para a autorização e deve ser tratado como um alerta de configuração.

Se a entrega exceder o tempo limite ou receber um 5xx transitório, repita exatamente o mesmo snapshot normalizado com a mesma revisão. Se a consulta à fonte de origem falhar, omita completamente o campo de janelas; nunca o substitua por uma matriz vazia.

Orientações sobre novas tentativas

Tente novamente estes com recuo exponencial limitado:

  • 429
  • 500
  • 502
  • 503
  • 504

Não repita estes cegamente:

  • 400
  • 401
  • 403
  • 404
  • 409
  • 422

No controle de acesso, sempre trate respostas de tempo limite e off-line como destravamentos com falha, a menos que suas próprias regras de acesso e processos de segurança determinem o contrário.

Detalhes a incluir ao contatar o suporte

Ao entrar em contato com o suporte, inclua:

  • Endpoint e método HTTP.
  • Data e hora, com o fuso horário.
  • ID da chave de parceiro, não a chave secreta.
  • Identificador de instalação usado.
  • ID do registro de origem no seu sistema.
  • Status e corpo da resposta.
  • event_id ou command_id, quando disponíveis.
{
  "success": false,
  "message": "Request body.members[0].member_id is required"
}

Alguns endpoints de domínios específicos retornam um status e um motivo explícitos. Por exemplo, as falhas de controle de acesso incluem campos como reason, door_id, facility_id e event_id.

{
  "status": "failed",
  "reason": "device_offline",
  "door_id": "00000000000000000000000000000007",
  "facility_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_id": "00000000-0000-0000-0000-000000000045"
}

400 Bad Request

A solicitação está malformada ou faltam campos obrigatórios. Corrija a solicitação antes de tentar novamente.

401 Unauthorized

A autenticação falhou. Verifique se você está usando HTTP Basic Auth com sua chave secreta de API como nome de usuário e uma senha vazia.

403 Forbidden

A chave é válida, mas a operação não é permitida. As causas comuns incluem usar uma chave somente leitura em uma operação de gravação ou tentar acessar uma instalação em que sua integração não está ativada.

404 Not Found

O recurso solicitado não foi encontrado ou não está disponível para sua integração.

409 Conflict

A solicitação entra em conflito com o estado atual do recurso. No controle de acesso, isso pode incluir um Door/Gate Controller em modo de manutenção.

422 Unprocessable Entity

A solicitação é um JSON válido, mas falha na validação semântica. Corrija os dados antes de tentar novamente.

429 Too Many Requests

A integração excedeu o limite de taxa documentado. Tente novamente com recuo exponencial.

500 Internal Server Error

O Performance Hub não conseguiu concluir a solicitação devido a um erro interno. Tente novamente com recuo. Se o problema persistir, entre em contato com o suporte informando o endpoint, o carimbo de data/hora e o corpo da resposta.

503 Service Unavailable

Um serviço ou dispositivo dependente está indisponível. Em destravamentos do Door/Gate Controller, isso pode significar que o controlador está off-line.

504 Gateway Timeout

A operação excedeu o tempo limite. Em destravamentos do Door/Gate Controller, isso significa que o destravamento não foi confirmado dentro do tempo limite.

Versionamento

A Partner API é versionada na URL. A versão atual é:

Política de alterações

O Performance Hub busca fazer alterações aditivas e compatíveis com versões anteriores sempre que possível.

Exemplos de alterações compatíveis com versões anteriores:

  • Adicionar um novo campo opcional a uma solicitação.
  • Adicionar um novo campo a uma resposta.
  • Adicionar um novo endpoint.
  • Adicionar um novo valor de enumeração quando se espera que os clientes tratem valores desconhecidos.
  • Melhorar as mensagens de validação sem alterar o contrato dos códigos de status.

access_time_windows e access_time_windows_revision são campos aditivos da solicitação de membro. Os clientes existentes que os omitem mantêm inalterado o snapshot de Access Time Windows armazenado. Essa regra de omissão preserva a compatibilidade com upserts parciais; omitir não equivale a enviar uma matriz vazia.

Exemplos de alterações incompatíveis:

  • Remover ou renomear um campo.
  • Alterar o tipo de um campo.
  • Tornar obrigatório um campo de solicitação opcional.
  • Remover um endpoint.
  • Alterar o significado de um código de status existente ou de um reason específico do domínio.

Descontinuações

Quando uma alteração incompatível for necessária, o Performance Hub evitará, sempre que possível, alterar a versão existente diretamente. Em vez disso, introduziremos uma nova versão ou um caminho de migração e comunicaremos a alteração aos parceiros afetados.

Os avisos de descontinuação podem incluir:

  • Uma entrada no registro de alterações.
  • Comunicação direta com os parceiros.
  • Observações no Partner Console.
  • Orientações de migração na documentação.

Recomendações para clientes

Crie clientes que tolerem alterações aditivas:

  • Ignore os campos de resposta que você não usa.
  • Trate valores de enumeração desconhecidos como não compatíveis, em vez de deixar o cliente falhar.
  • Evite verificações estritas de igualdade das respostas.
  • Registre valores não reconhecidos para que você possa atualizar sua integração de forma intencional.

Para partições de membro com revisão, como as Access Time Windows, mantenha a revisão enviada e o payload normalizado até que o resultado seja conhecido. Reutilizar uma revisão para um conteúdo alterado é um conflito, enquanto repetir o mesmo conteúdo é idempotente. Consulte Access Time Windows.

Especificações OpenAPI

Use as especificações OpenAPI publicadas para gerar clientes, validar solicitações e acompanhar as mudanças na estrutura da API ao longo do tempo.

Consulte Especificações OpenAPI.

https://partner-api.performancehub.co/partner/v1/

Registro de alterações

Este registro de alterações documenta mudanças relevantes na Partner API e no Partner Console que afetam o comportamento das integrações.

2026-09-09

2026-05-06

2026-05-01

Categorias de alteração

As próximas entradas usam estas categorias:

  • Adicionado - novo endpoint, campo, guia ou recurso.
  • Alterado - comportamento ou documentação alterados sem remoção de suporte.
  • Obsoleto - o recurso continua disponível, mas tem um caminho de migração planejado.
  • Removido - recurso ou endpoint removido.
  • Corrigido - correção de bug ou da documentação.
  • Segurança - alteração de autenticação, autorização, tratamento de dados ou gerenciamento de chaves.

Adicionado

  • Adicionados snapshots access_time_windows de membros, independentes de fornecedor, com janelas absolutas e semanais recorrentes combinadas.
  • Adicionada a semântica de ordenação por access_time_windows_revision, repetição idempotente, conflito, descarte de dados desatualizados e revogação explícita.
  • Adicionadas orientações sobre fusos horários IANA, horário de verão, mapeamento lógico de scope_key, atualização dos dados de origem, implementação pelo produtor e certificação.

Adicionado

  • Adicionada documentação do programa de parceiros, abrangendo tipos de parceiros, integração, práticas recomendadas, preparação para a entrada em produção, erros, versionamento e suporte.
  • Adicionado um fluxo dedicado de solicitação Torne-se um parceiro para possíveis parceiros técnicos e comerciais.
  • Adicionada documentação sobre como as integrações de parceiros aprovadas aparecem no diretório de parceiros do Performance Hub, na plataforma principal do Performance Hub.

Adicionado

  • Adicionada documentação de controle de acesso do Door/Gate Controller, incluindo as operações de listagem, status e destravamento.
  • Adicionada documentação do comportamento síncrono de destravamento: a API retorna sucesso somente depois que o controlador local confirma que o relé foi fisicamente destravado.
  • Adicionada documentação do suporte ao idempotency_key opcional em solicitações de destravamento do Door/Gate Controller.