API Atura
Download SAF-T
Conformidade ATFaz download dos ficheiros SAF-T gerados de forma segura, com validação de integridade e gestão de expiração.
Documentação em Desenvolvimento
Esta documentação está ainda em desenvolvimento ativo. Algumas secções podem estar incompletas ou sujeitas a alterações. Para questões específicas, contacta o nosso suporte técnico.
Download Seguro de Ficheiros
Os ficheiros SAF-T são disponibilizados através de URLs seguras com tempo limitado, garantindo a integridade e confidencialidade dos dados fiscais.
Seguro
URLs temporárias e autenticadas
Validado
Verificação de integridade SHA-256
Auditável
Log completo de downloads
Download de Ficheiro
/v1/saft/download/{id}Faz download do ficheiro SAF-T gerado usando o ID da geração. O ficheiro é devolvido em formato XML.
Headers de Segurança
O download inclui headers para validação de integridade (MD5 e SHA-256) e informações sobre a geração e expiração do ficheiro.
Exemplo de Pedido
GET /v1/saft/download/saft_gen_abc123def456
Authorization: Bearer atura_live_1234...
Accept: application/xmlResposta
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Disposition: attachment; filename="SAFT_PT_123456789_2025_01.xml"
Content-Length: 2456789
Content-MD5: a1b2c3d4e5f6789abcdef0123456789a
X-File-Hash: sha256:a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a
X-Generated-At: 2025-01-15T14:35:12Z
X-Expires-At: 2025-01-22T14:35:00Z
<?xml version="1.0" encoding="UTF-8"?>
<ns2:AuditFile xmlns:ns2="urn:OECD:StandardAuditFile-Tax:PT_1.04_01"
xmlns="http://www.w3.org/2001/XMLSchema-instance">
<ns2:Header>
<ns2:AuditFileVersion>1.04_01</ns2:AuditFileVersion>
<ns2:CompanyID>123456789</ns2:CompanyID>
<!-- Conteúdo completo do SAF-T -->
</ns2:Header>
<!-- ... resto do ficheiro XML ... -->
</ns2:AuditFile>URL de Download Direto
Quando o SAF-T está concluído, podes usar o campo download_urlda resposta de estado para download direto sem chamadas API adicionais.
Exemplo com cURL
# Download direto usando a URL fornecida
curl -H "Authorization: Bearer atura_live_1234..." \
-o "SAFT_PT_123456789_2025_01.xml" \
"https://api.atura.pt/saft/download/saft_gen_abc123def456"
# Verificar integridade do ficheiro
shasum -a 256 SAFT_PT_123456789_2025_01.xml
# Deve coincidir com o hash fornecido no header X-File-HashExemplo com Python
import requests
import hashlib
# Configuração
api_key = "atura_live_1234..."
generation_id = "saft_gen_abc123def456"
url = f"https://api.atura.pt/v1/saft/download/{generation_id}"
# Headers
headers = {
"Authorization": f"Bearer {api_key}",
"Accept": "application/xml"
}
# Download
response = requests.get(url, headers=headers, stream=True)
response.raise_for_status()
# Extrair informações dos headers
filename = response.headers.get('Content-Disposition', '').split('filename=')[1].strip('"')
expected_hash = response.headers.get('X-File-Hash', '').replace('sha256:', '')
content_length = int(response.headers.get('Content-Length', 0))
print(f"A fazer download de {filename} ({content_length:,} bytes)...")
# Guardar ficheiro e calcular hash
sha256_hash = hashlib.sha256()
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
sha256_hash.update(chunk)
# Verificar integridade
file_hash = sha256_hash.hexdigest()
if file_hash == expected_hash:
print(f"✅ Ficheiro {filename} descarregado e verificado com sucesso")
else:
print(f"❌ Erro: Hash não coincide. Esperado: {expected_hash}, Obtido: {file_hash}")
raise ValueError("Falha na verificação de integridade do ficheiro")Histórico de Downloads
/v1/saft/download/{id}/historyConsulta o histórico de downloads de um ficheiro SAF-T para auditoria e controlo.
Resposta
{
"generation_id": "saft_gen_abc123def456",
"file": {
"filename": "SAFT_PT_123456789_2025_01.xml",
"size": 2456789,
"created_at": "2025-01-15T14:35:12Z",
"expires_at": "2025-01-22T14:35:00Z"
},
"downloads": [
{
"id": "download_xyz789uvw012",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 (compatible; AturaClient/1.0)",
"downloaded_at": "2025-01-15T15:22:33Z",
"download_duration": 12.5,
"bytes_transferred": 2456789,
"integrity_verified": true,
"status": "completed"
},
{
"id": "download_def456ghi789",
"ip_address": "203.0.113.42",
"user_agent": "curl/7.68.0",
"downloaded_at": "2025-01-16T09:15:44Z",
"download_duration": 8.2,
"bytes_transferred": 2456789,
"integrity_verified": true,
"status": "completed"
}
],
"total_downloads": 2,
"total_bytes_transferred": 4913578
}Download em Lote
/v1/saft/download/bulkCria um arquivo ZIP com vários ficheiros SAF-T para download conveniente de múltiplos períodos.
Exemplo de Pedido
POST /v1/saft/download/bulk
Content-Type: application/json
Authorization: Bearer atura_live_1234...
{
"generation_ids": [
"saft_gen_abc123def456", // Janeiro 2025
"saft_gen_xyz789uvw012", // Dezembro 2024
"saft_gen_mno345pqr678" // Novembro 2024
],
"archive_name": "SAFT_Q4_2024_Q1_2025",
"include_manifest": true
}Resposta
{
"bulk_id": "bulk_download_abc123",
"status": "processing",
"archive_name": "SAFT_Q4_2024_Q1_2025.zip",
"files_included": 3,
"estimated_size": 7234567,
"progress": {
"current_file": 1,
"total_files": 3,
"percentage": 33
},
"download_url": null, // Disponível quando concluído
"created_at": "2025-01-15T16:00:00Z",
"expires_at": "2025-01-16T16:00:00Z" // 24h após criação
}Validação de Ficheiros
/v1/saft/validateValida a integridade e conformidade de um ficheiro SAF-T descarregado.
Exemplo de Pedido
POST /v1/saft/validate
Content-Type: application/json
Authorization: Bearer atura_live_1234...
{
"generation_id": "saft_gen_abc123def456",
"file_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"hash_algorithm": "sha256",
"perform_schema_validation": true,
"perform_business_rules_validation": true
}Resposta
{
"generation_id": "saft_gen_abc123def456",
"validation_result": {
"integrity_check": {
"status": "passed",
"expected_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"provided_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"match": true
},
"schema_validation": {
"status": "passed",
"schema_version": "1.04_01",
"errors": [],
"warnings": []
},
"business_rules_validation": {
"status": "passed",
"rules_checked": 47,
"errors": [],
"warnings": [
{
"code": "W001",
"message": "Documento sem observações pode indicar falta de informação",
"line": 2847,
"severity": "low"
}
]
}
},
"overall_status": "valid",
"validated_at": "2025-01-15T16:30:00Z"
}Tratamento de Erros
404 Not Found
Ficheiro não encontrado ou expirado.
{
"error": {
"type": "not_found_error",
"code": "file_not_found",
"message": "Ficheiro SAF-T não encontrado ou expirado",
"details": {
"generation_id": "saft_gen_invalid123",
"possible_causes": [
"ID de geração inválido",
"Ficheiro expirou (>7 dias)",
"Geração ainda em processamento"
]
}
}
}410 Gone
Ficheiro permanentemente removido.
{
"error": {
"type": "resource_gone_error",
"code": "file_expired",
"message": "Ficheiro SAF-T expirou e foi removido permanentemente",
"details": {
"generation_id": "saft_gen_abc123def456",
"expired_at": "2025-01-22T14:35:00Z",
"retention_days": 7,
"suggestion": "Gere novamente o SAF-T para o mesmo período"
}
}
}409 Conflict
Ficheiro ainda em processamento.
{
"error": {
"type": "conflict_error",
"code": "generation_in_progress",
"message": "Geração SAF-T ainda em processamento",
"details": {
"generation_id": "saft_gen_abc123def456",
"status": "processing",
"progress_percentage": 67,
"estimated_completion": "2025-01-15T14:35:00Z"
}
}
}Segurança e Retenção
Os ficheiros SAF-T são automaticamente removidos após 7 dias por motivos de segurança. Certifica-te de fazer download e backup dos ficheiros dentro deste prazo.
Download SAF-T
Conformidade ATFaz download dos ficheiros SAF-T gerados de forma segura, com validação de integridade e gestão de expiração.
Documentação em Desenvolvimento
Esta documentação está ainda em desenvolvimento ativo. Algumas secções podem estar incompletas ou sujeitas a alterações. Para questões específicas, contacta o nosso suporte técnico.
Download Seguro de Ficheiros
Os ficheiros SAF-T são disponibilizados através de URLs seguras com tempo limitado, garantindo a integridade e confidencialidade dos dados fiscais.
Seguro
URLs temporárias e autenticadas
Validado
Verificação de integridade SHA-256
Auditável
Log completo de downloads
Download de Ficheiro
/v1/saft/download/{id}Faz download do ficheiro SAF-T gerado usando o ID da geração. O ficheiro é devolvido em formato XML.
Headers de Segurança
O download inclui headers para validação de integridade (MD5 e SHA-256) e informações sobre a geração e expiração do ficheiro.
Exemplo de Pedido
GET /v1/saft/download/saft_gen_abc123def456
Authorization: Bearer atura_live_1234...
Accept: application/xmlResposta
HTTP/1.1 200 OK
Content-Type: application/xml
Content-Disposition: attachment; filename="SAFT_PT_123456789_2025_01.xml"
Content-Length: 2456789
Content-MD5: a1b2c3d4e5f6789abcdef0123456789a
X-File-Hash: sha256:a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a
X-Generated-At: 2025-01-15T14:35:12Z
X-Expires-At: 2025-01-22T14:35:00Z
<?xml version="1.0" encoding="UTF-8"?>
<ns2:AuditFile xmlns:ns2="urn:OECD:StandardAuditFile-Tax:PT_1.04_01"
xmlns="http://www.w3.org/2001/XMLSchema-instance">
<ns2:Header>
<ns2:AuditFileVersion>1.04_01</ns2:AuditFileVersion>
<ns2:CompanyID>123456789</ns2:CompanyID>
<!-- Conteúdo completo do SAF-T -->
</ns2:Header>
<!-- ... resto do ficheiro XML ... -->
</ns2:AuditFile>URL de Download Direto
Quando o SAF-T está concluído, podes usar o campo download_urlda resposta de estado para download direto sem chamadas API adicionais.
Exemplo com cURL
# Download direto usando a URL fornecida
curl -H "Authorization: Bearer atura_live_1234..." \
-o "SAFT_PT_123456789_2025_01.xml" \
"https://api.atura.pt/saft/download/saft_gen_abc123def456"
# Verificar integridade do ficheiro
shasum -a 256 SAFT_PT_123456789_2025_01.xml
# Deve coincidir com o hash fornecido no header X-File-HashExemplo com Python
import requests
import hashlib
# Configuração
api_key = "atura_live_1234..."
generation_id = "saft_gen_abc123def456"
url = f"https://api.atura.pt/v1/saft/download/{generation_id}"
# Headers
headers = {
"Authorization": f"Bearer {api_key}",
"Accept": "application/xml"
}
# Download
response = requests.get(url, headers=headers, stream=True)
response.raise_for_status()
# Extrair informações dos headers
filename = response.headers.get('Content-Disposition', '').split('filename=')[1].strip('"')
expected_hash = response.headers.get('X-File-Hash', '').replace('sha256:', '')
content_length = int(response.headers.get('Content-Length', 0))
print(f"A fazer download de {filename} ({content_length:,} bytes)...")
# Guardar ficheiro e calcular hash
sha256_hash = hashlib.sha256()
with open(filename, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
sha256_hash.update(chunk)
# Verificar integridade
file_hash = sha256_hash.hexdigest()
if file_hash == expected_hash:
print(f"✅ Ficheiro {filename} descarregado e verificado com sucesso")
else:
print(f"❌ Erro: Hash não coincide. Esperado: {expected_hash}, Obtido: {file_hash}")
raise ValueError("Falha na verificação de integridade do ficheiro")Histórico de Downloads
/v1/saft/download/{id}/historyConsulta o histórico de downloads de um ficheiro SAF-T para auditoria e controlo.
Resposta
{
"generation_id": "saft_gen_abc123def456",
"file": {
"filename": "SAFT_PT_123456789_2025_01.xml",
"size": 2456789,
"created_at": "2025-01-15T14:35:12Z",
"expires_at": "2025-01-22T14:35:00Z"
},
"downloads": [
{
"id": "download_xyz789uvw012",
"ip_address": "203.0.113.42",
"user_agent": "Mozilla/5.0 (compatible; AturaClient/1.0)",
"downloaded_at": "2025-01-15T15:22:33Z",
"download_duration": 12.5,
"bytes_transferred": 2456789,
"integrity_verified": true,
"status": "completed"
},
{
"id": "download_def456ghi789",
"ip_address": "203.0.113.42",
"user_agent": "curl/7.68.0",
"downloaded_at": "2025-01-16T09:15:44Z",
"download_duration": 8.2,
"bytes_transferred": 2456789,
"integrity_verified": true,
"status": "completed"
}
],
"total_downloads": 2,
"total_bytes_transferred": 4913578
}Download em Lote
/v1/saft/download/bulkCria um arquivo ZIP com vários ficheiros SAF-T para download conveniente de múltiplos períodos.
Exemplo de Pedido
POST /v1/saft/download/bulk
Content-Type: application/json
Authorization: Bearer atura_live_1234...
{
"generation_ids": [
"saft_gen_abc123def456", // Janeiro 2025
"saft_gen_xyz789uvw012", // Dezembro 2024
"saft_gen_mno345pqr678" // Novembro 2024
],
"archive_name": "SAFT_Q4_2024_Q1_2025",
"include_manifest": true
}Resposta
{
"bulk_id": "bulk_download_abc123",
"status": "processing",
"archive_name": "SAFT_Q4_2024_Q1_2025.zip",
"files_included": 3,
"estimated_size": 7234567,
"progress": {
"current_file": 1,
"total_files": 3,
"percentage": 33
},
"download_url": null, // Disponível quando concluído
"created_at": "2025-01-15T16:00:00Z",
"expires_at": "2025-01-16T16:00:00Z" // 24h após criação
}Validação de Ficheiros
/v1/saft/validateValida a integridade e conformidade de um ficheiro SAF-T descarregado.
Exemplo de Pedido
POST /v1/saft/validate
Content-Type: application/json
Authorization: Bearer atura_live_1234...
{
"generation_id": "saft_gen_abc123def456",
"file_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"hash_algorithm": "sha256",
"perform_schema_validation": true,
"perform_business_rules_validation": true
}Resposta
{
"generation_id": "saft_gen_abc123def456",
"validation_result": {
"integrity_check": {
"status": "passed",
"expected_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"provided_hash": "a1b2c3d4e5f6789abcdef0123456789abcdef0123456789abcdef0123456789a",
"match": true
},
"schema_validation": {
"status": "passed",
"schema_version": "1.04_01",
"errors": [],
"warnings": []
},
"business_rules_validation": {
"status": "passed",
"rules_checked": 47,
"errors": [],
"warnings": [
{
"code": "W001",
"message": "Documento sem observações pode indicar falta de informação",
"line": 2847,
"severity": "low"
}
]
}
},
"overall_status": "valid",
"validated_at": "2025-01-15T16:30:00Z"
}Tratamento de Erros
404 Not Found
Ficheiro não encontrado ou expirado.
{
"error": {
"type": "not_found_error",
"code": "file_not_found",
"message": "Ficheiro SAF-T não encontrado ou expirado",
"details": {
"generation_id": "saft_gen_invalid123",
"possible_causes": [
"ID de geração inválido",
"Ficheiro expirou (>7 dias)",
"Geração ainda em processamento"
]
}
}
}410 Gone
Ficheiro permanentemente removido.
{
"error": {
"type": "resource_gone_error",
"code": "file_expired",
"message": "Ficheiro SAF-T expirou e foi removido permanentemente",
"details": {
"generation_id": "saft_gen_abc123def456",
"expired_at": "2025-01-22T14:35:00Z",
"retention_days": 7,
"suggestion": "Gere novamente o SAF-T para o mesmo período"
}
}
}409 Conflict
Ficheiro ainda em processamento.
{
"error": {
"type": "conflict_error",
"code": "generation_in_progress",
"message": "Geração SAF-T ainda em processamento",
"details": {
"generation_id": "saft_gen_abc123def456",
"status": "processing",
"progress_percentage": 67,
"estimated_completion": "2025-01-15T14:35:00Z"
}
}
}Segurança e Retenção
Os ficheiros SAF-T são automaticamente removidos após 7 dias por motivos de segurança. Certifica-te de fazer download e backup dos ficheiros dentro deste prazo.