ITMS-91053: como corrigir “Missing API declaration” no Expo
Por Mehdi Azizi
Publicado em , 8 min
ITMS-91053: seu build usa uma API de motivo obrigatório sem declarar. Adicione a categoria e o código em ios.privacyManifests e faça um novo build.
ITMS-91053 é uma verificação automática da Apple, enviada por e-mail depois da entrega do seu build. Ela diz que o código do seu app usa uma API "de motivo obrigatório" (preferências, datas de arquivos, tempo desde a inicialização, espaço em disco ou teclados) sem explicar o porquê no manifesto de privacidade. No Expo, a correção é feita em ios.privacyManifests: a categoria citada pela Apple, o código que descreve o seu uso real e depois um novo build.
No Solys, meu despertador com minijogos, esses motivos ficam declarados na configuração do app. Aqui está a declaração real dele, o comando que lista o que as suas dependências usam e a verificação que você deve fazer no arquivo final antes do envio.
O que significa o erro ITMS-91053?
A mensagem se chama "ITMS-91053: Missing API declaration". Ela informa que o código de um arquivo específico do seu build faz referência a uma ou mais APIs que exigem um motivo. Depois, lista as categorias envolvidas, por exemplo NSPrivacyAccessedAPICategoryUserDefaults.
Essas APIs não pedem nenhuma permissão ao usuário. Mas elas podem servir para identificar um aparelho, o que a Apple chama de fingerprinting. Isso é proibido, mesmo quando o usuário aceita o rastreamento. A Apple explica isso na página sobre as APIs de motivo obrigatório: cada app e cada SDK precisa declarar por que as usa.
A mesma página define a regra: desde 1º de maio de 2024, o App Store Connect não aceita mais um app que não descreva esses usos no manifesto. Alguns desenvolvedores relataram esse e-mail como um simples aviso, num build aceito. Não conte com isso: trate como um bloqueio e corrija antes do próximo envio.
Como os outros erros ITMS, isso não é uma rejeição de um revisor. Ninguém abriu o seu app: a Apple analisou o binário.
O privacy manifest do iOS: o arquivo PrivacyInfo.xcprivacy
O manifesto de privacidade é um arquivo chamado PrivacyInfo.xcprivacy, colocado na raiz do bundle do app. Segundo a documentação da Apple sobre privacy manifests, ele descreve os dados coletados, o rastreamento e as APIs de motivo obrigatório. Essas últimas ficam no array NSPrivacyAccessedAPITypes: uma entrada por categoria, com o tipo e a lista de motivos.
A pegadinha: um manifesto só cobre o próprio bundle. A Apple deixa isso escrito: cada executável ou biblioteca dinâmica que usa essas APIs precisa ter um manifesto no seu bundle. O do seu app não cobre um framework embutido, e um SDK não pode depender do manifesto do seu app.
Não confunda com as frases do Info.plist exigidas pelo ITMS-90683. Essas aparecem para o usuário num pedido de permissão. O manifesto, por outro lado, só é lido pela Apple.
As 5 categorias de API e seus códigos de motivo
O nome completo de uma categoria começa com NSPrivacyAccessedAPICategory. A lista de APIs e motivos está na página da chave NSPrivacyAccessedAPIType, consultada em 15 de outubro de 2026.
| Categoria | API típica | Motivo comum |
|---|---|---|
| UserDefaults | UserDefaults | CA92.1 |
| FileTimestamp | creationDate | C617.1 |
| SystemBootTime | systemUptime | 35F9.1 |
| DiskSpace | volumeAvailableCapacityKey | E174.1 |
| ActiveKeyboards | activeInputModes | 54BD.1 |
Os códigos que você mais vai encontrar:
- CA92.1: o app lê e grava as próprias preferências, inacessíveis para outros apps.
- 1C8F.1: preferências compartilhadas com um widget ou uma extensão do mesmo App Group.
- C617.1: datas ou tamanho de arquivos guardados no contêiner do app.
- 3B52.1: arquivos escolhidos pelo usuário, por exemplo num seletor de documentos.
- 35F9.1: medir o tempo decorrido entre dois eventos do app, ou rodar um timer.
- E174.1: verificar o espaço livre antes de gravar arquivos, com um efeito visível para o usuário.
- 85F4.1: mostrar o espaço em disco para o usuário.
Declare o motivo que corresponde ao seu uso real, não o que parece mais amplo. A Apple especifica que essas APIs e seus dados só servem para os motivos declarados, e nunca para rastreamento. Dois códigos são reservados para SDKs de terceiros: C56D.1 e 0A2A.1. Eles não têm lugar no manifesto do seu app.
Declarar o privacy manifest no Expo
No Expo, você não escreve o arquivo na mão. Você o descreve em expo.ios.privacyManifests, no app.json ou no app.config, e o prebuild gera o PrivacyInfo.xcprivacy. Esse é o método da documentação do Expo sobre privacy manifests.
Aqui está o trecho real da configuração do Solys. A chave também contém o rastreamento e os dados coletados, removidos aqui:
{
"expo": {
"ios": {
"privacyManifests": {
"NSPrivacyAccessedAPITypes": [
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
"NSPrivacyAccessedAPITypeReasons": ["CA92.1", "1C8F.1"]
},
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
"NSPrivacyAccessedAPITypeReasons": ["C617.1"]
},
{
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
"NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
}
]
}
}
}
}
CA92.1, C617.1 e 35F9.1 repetem o que o React Native e os módulos Expo do app declaram. O 1C8F.1 vem do próprio Solys: o app compartilha configurações com o widget por meio de um App Group.
Uma pegadinha que vale conhecer: se a sua pasta ios é gerada e ignorada pelo git, um PrivacyInfo.xcprivacy escrito à mão nessa pasta nunca chega ao build. O EAS roda o prebuild de novo e regenera a pasta. Vi isso acontecer num dos meus projetos em 9 de setembro de 2026: o manifesto escrito à mão tinha sumido depois de um prebuild. A declaração precisa ficar na configuração.
Último ponto: o manifesto faz parte do binário. Uma atualização remota não muda nada nele. Você precisa fazer um novo build e enviar de novo.
Os SDKs de terceiros que trazem o próprio manifesto
A maioria das bibliotecas recentes fornece seu manifesto. Os pacotes Expo que usam essas APIs têm um PrivacyInfo.xcprivacy na pasta ios, assim como o React Native. O problema vem da forma como eles são vinculados ao seu app.
A documentação do Expo avisa: a Apple não lê corretamente todos os manifestos das dependências CocoaPods vinculadas estaticamente, que é o caso dos pacotes Expo. Então pode ser necessário copiar os motivos deles na configuração do seu app.
Para reduzir esse trabalho, a opção ios.privacyManifestAggregationEnabled do expo-build-properties junta os manifestos das dependências CocoaPods num único arquivo. No Podfile que o Expo gera nos meus projetos (SDK 57), essa junção vem ativada, a menos que você a desative.
A junção tem um limite: ela só enxerga as dependências que fornecem um manifesto. Uma biblioteca antiga sem manifesto continua invisível. Por isso, leia o caminho do arquivo citado no e-mail: ele diz onde corrigir.
| Arquivo citado | Onde corrigir |
|---|---|
| O executável do app | ios.privacyManifests |
Um .framework | Atualizar o SDK |
Uma extensão .appex | Manifesto da extensão |
Verificar antes do envio
O Expo sugere esperar o e-mail da Apple depois de um envio. Funciona, mas cada ida e volta custa um build. Estas são as quatro verificações que eu faço antes.
1. Liste o que as suas dependências declaram. A partir da raiz do projeto:
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
-exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
No Solys, em 15 de outubro de 2026, o comando encontra 13 manifestos e quatro categorias: datas de arquivos, preferências, tempo desde a inicialização e espaço em disco. Cada categoria listada precisa aparecer no manifesto final do app, ou no do framework que a usa.
2. Procure no seu próprio código nativo. Módulos próprios, plugins, targets como um widget: esse código nenhum SDK vai declarar por você.
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
--include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
Adapte as pastas ao seu projeto. No Solys, é essa busca que revela as preferências compartilhadas por App Group, daí o código 1C8F.1.
3. Leia o manifesto gerado. Rode npx expo prebuild -p ios e abra ios/<NomDeTonApp>/PrivacyInfo.xcprivacy. Atenção: esse comando pode apagar e recriar a pasta ios. Se você fez alterações à mão nela, trabalhe numa cópia do projeto.
4. Verifique o build final. É a única prova que conta. Baixe o IPA na página do build no expo.dev e rode no seu Mac:
unzip -q MonApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
A segunda linha lista todos os manifestos embutidos, o do app e os dos frameworks. A terceira mostra o do app, para comparar com a lista do passo 1.
O que o manifesto precisa dizer junto com a sua página na loja
O manifesto não vive sozinho. Se ele declara rastreamento ou dados coletados, a sua página na App Store e a sua política de privacidade precisam dizer a mesma coisa. Uma diferença entre os três pode depois custar uma rejeição humana, com base na guideline 5.1.1. O que precisa ser alinhado está detalhado em política de privacidade de um aplicativo.
Enviar seu build sem surpresas
Os erros ITMS se corrigem rápido quando você sabe lê-los. As rejeições que vêm depois exigem mais calma: o passo a passo está na página aplicativo rejeitado pela Apple, e os motivos mais comuns estão em por que a Apple rejeita um app.
Para conferir tudo antes do envio, o Apple Review Kit reúne meu checklist e skills do Claude Code que revisam o seu projeto. Se o seu envio travou e você quer um olhar humano, agende uma hora comigo: a gente revisa o seu projeto por videochamada, na sua tela. E se você está preparando o seu primeiro lançamento, faça seu diagnóstico gratuito: ele coloca as etapas na ordem e te envia meu checklist antirrejeição da Apple.
Perguntas frequentes
O ITMS-91053 bloqueia o envio do meu build?
A Apple diz que, desde 1º de maio de 2024, o App Store Connect não aceita mais apps que não descrevam o uso dessas APIs. Mesmo assim, alguns desenvolvedores receberam o e-mail num build aceito, como um aviso. Em qualquer caso, corrija o manifesto antes do próximo build.
Qual código de motivo escolher para UserDefaults?
CA92.1 se o app só lê e grava as próprias preferências. Adicione 1C8F.1 se ele as compartilha com um widget ou uma extensão por um App Group. O C56D.1 é reservado para SDKs de terceiros: não coloque no manifesto do seu app.
Preciso copiar o manifesto de cada SDK no app.json?
Não necessariamente. Se a junção de manifestos estiver ativa, os das dependências CocoaPods são reunidos na instalação dos pods. Copie uma categoria só se ela estiver faltando no manifesto final, com o motivo que descreve o uso real.
Meu widget ou minha extensão precisa de um manifesto próprio?
Segundo a Apple, cada bundle que contém um executável que usa essas APIs precisa ter o próprio manifesto. Uma extensão é um executável separado, no próprio bundle: o manifesto do app não a cobre.
Dá para corrigir o ITMS-91053 sem fazer um novo build?
Não. O manifesto de privacidade faz parte do binário. Corrija a configuração, faça um novo build e teste no TestFlight antes de enviar para revisão.