Atura
Atura

API Atura

Download SAF-T

Conformidade AT

Faz 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

GET/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

JSON
GET /v1/saft/download/saft_gen_abc123def456
Authorization: Bearer atura_live_1234...
Accept: application/xml

Resposta

JSON
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

Bash
# 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-Hash

Exemplo com Python

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

GET/v1/saft/download/{id}/history

Consulta o histórico de downloads de um ficheiro SAF-T para auditoria e controlo.

Resposta

JSON
{
  "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

POST/v1/saft/download/bulk

Cria um arquivo ZIP com vários ficheiros SAF-T para download conveniente de múltiplos períodos.

Exemplo de Pedido

JSON
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

JSON
{
  "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

POST/v1/saft/validate

Valida a integridade e conformidade de um ficheiro SAF-T descarregado.

Exemplo de Pedido

JSON
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

JSON
{
  "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.

JSON
{
  "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.

JSON
{
  "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.

JSON
{
  "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.