{
  "openapi": "3.1.0",
  "info": {
    "title": "PROFOYO Public API",
    "version": "2026-07-09",
    "summary": "Public REST API for compliance-verified Dutch freelancer engagements.",
    "description": "Programmatic access to PROFOYO's compliance layer: risk scoring under the Zelfstandigenwet, WTTA admission checks, rate benchmarks, Compliance Passport verification and DAC7 seller data. Designed for VMS, ATS and accounting integrations.\n\nAuthentication: all endpoints require an API access token minted at `/freelancer/api-tokens` and passed as `Authorization: Bearer <token>`. Sandbox tokens (prefix `sk_test_`) route to the sandbox project and never touch production data.",
    "contact": {
      "name": "PROFOYO Developer Platform",
      "email": "info@profoyo.com",
      "url": "https://profoyo.nl/developers"
    },
    "license": {
      "name": "PROFOYO API Terms",
      "url": "https://profoyo.nl/legal/api-terms"
    },
    "termsOfService": "https://profoyo.nl/legal/api-terms"
  },
  "servers": [
    { "url": "https://api.profoyo.com/v1", "description": "Production" },
    { "url": "https://sandbox-api.profoyo.com/v1", "description": "Sandbox (test data only, no persistence >30d)" }
  ],
  "tags": [
    { "name": "Compliance", "description": "Risk scoring and verdicts." },
    { "name": "Passport", "description": "Compliance Passport verification." },
    { "name": "WTTA", "description": "Wet toelating terbeschikkingstelling admission cache." },
    { "name": "Rates", "description": "Sector rate benchmarks." },
    { "name": "DAC7", "description": "EU DAC7 seller report data." }
  ],
  "paths": {
    "/health": {
      "get": {
        "tags": ["Compliance"],
        "summary": "Service health",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "enum": ["ok", "degraded", "down"] },
                    "region": { "type": "string", "example": "eu-central-1" },
                    "version": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/classify/zelfstandigenwet": {
      "post": {
        "tags": ["Compliance"],
        "summary": "Score an engagement against the Zelfstandigenwet 5+4 framework",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ZWClassifyRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verdict",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ZWVerdict" }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/classify/cross-border": {
      "post": {
        "tags": ["Compliance"],
        "summary": "Score an engagement against a foreign self-employment test (FR/DE/BE)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CrossBorderRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Verdict",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CrossBorderVerdict" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/wtta/lookup": {
      "get": {
        "tags": ["WTTA"],
        "summary": "Look up WTTA admission by KvK number",
        "parameters": [
          {
            "name": "kvk",
            "in": "query",
            "required": true,
            "schema": { "type": "string", "pattern": "^[0-9]{8}$" }
          }
        ],
        "responses": {
          "200": {
            "description": "Admission record",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/WttaAdmission" }
              }
            }
          },
          "404": { "description": "Not in cache" }
        }
      }
    },
    "/rates/benchmark": {
      "get": {
        "tags": ["Rates"],
        "summary": "Sector rate benchmark",
        "parameters": [
          { "name": "sector", "in": "query", "required": true, "schema": { "type": "string" } },
          { "name": "region", "in": "query", "schema": { "type": "string", "default": "NL" } }
        ],
        "responses": {
          "200": {
            "description": "Benchmark",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/RateBenchmark" }
              }
            }
          }
        }
      }
    },
    "/passport/{token}/verify": {
      "get": {
        "tags": ["Passport"],
        "summary": "Verify a Compliance Passport share-token",
        "parameters": [
          { "name": "token", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Passport summary",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/PassportSummary" }
              }
            }
          },
          "404": { "description": "Expired or unknown" }
        }
      }
    },
    "/dac7/seller/{freelancer_id}": {
      "get": {
        "tags": ["DAC7"],
        "summary": "Fetch the current-year DAC7 seller report snapshot",
        "parameters": [
          { "name": "freelancer_id", "in": "path", "required": true, "schema": { "type": "string", "format": "uuid" } }
        ],
        "responses": {
          "200": {
            "description": "Seller report",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Dac7Seller" }
              }
            }
          },
          "403": { "description": "Not authorised for this seller" }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "opaque",
        "description": "Bearer token minted at /freelancer/api-tokens. Sandbox tokens carry the `sk_test_` prefix."
      }
    },
    "responses": {
      "BadRequest": { "description": "Validation error" },
      "Unauthorized": { "description": "Missing or invalid bearer token" },
      "RateLimited": {
        "description": "Rate limit exceeded. See headers X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After."
      }
    },
    "schemas": {
      "ZWClassifyRequest": {
        "type": "object",
        "required": ["engagement"],
        "properties": {
          "engagement": {
            "type": "object",
            "properties": {
              "hourly_rate_eur": { "type": "number" },
              "months_duration": { "type": "integer" },
              "days_per_week": { "type": "integer" },
              "other_clients_count": { "type": "integer" },
              "own_tools": { "type": "boolean" },
              "own_liability": { "type": "boolean" },
              "sets_own_hours": { "type": "boolean" },
              "can_delegate": { "type": "boolean" },
              "profit_risk": { "type": "boolean" }
            }
          }
        }
      },
      "ZWVerdict": {
        "type": "object",
        "properties": {
          "verdict": { "type": "string", "enum": ["safe", "risky", "unsafe"] },
          "score": { "type": "number" },
          "ratio": { "type": "number" },
          "criteria_hit": { "type": "array", "items": { "type": "string" } },
          "advice": { "type": "string" }
        }
      },
      "CrossBorderRequest": {
        "type": "object",
        "required": ["country", "criteria"],
        "properties": {
          "country": { "type": "string", "enum": ["FR", "DE", "BE"] },
          "criteria": { "type": "object", "additionalProperties": { "type": "boolean" } }
        }
      },
      "CrossBorderVerdict": {
        "type": "object",
        "properties": {
          "verdict": { "type": "string", "enum": ["safe", "risky", "unsafe"] },
          "law": { "type": "string" },
          "tariefgrens_min_eur": { "type": "number" },
          "advice": { "type": "string" }
        }
      },
      "WttaAdmission": {
        "type": "object",
        "properties": {
          "kvk_number": { "type": "string" },
          "legal_name": { "type": "string" },
          "admission_status": {
            "type": "string",
            "enum": ["unknown", "applied", "admitted", "conditionally_admitted", "revoked", "suspended", "expired", "not_required"]
          },
          "admission_number": { "type": "string" },
          "admitted_at": { "type": "string", "format": "date-time" },
          "expires_at": { "type": "string", "format": "date-time" },
          "source": { "type": "string" },
          "source_url": { "type": "string", "format": "uri" },
          "last_verified_at": { "type": "string", "format": "date-time" }
        }
      },
      "RateBenchmark": {
        "type": "object",
        "properties": {
          "sector": { "type": "string" },
          "region": { "type": "string" },
          "p25_eur": { "type": "number" },
          "p50_eur": { "type": "number" },
          "p75_eur": { "type": "number" },
          "sample_size": { "type": "integer" },
          "as_of": { "type": "string", "format": "date" }
        }
      },
      "PassportSummary": {
        "type": "object",
        "properties": {
          "freelancer_id": { "type": "string", "format": "uuid" },
          "issued_at": { "type": "string", "format": "date-time" },
          "expires_at": { "type": "string", "format": "date-time" },
          "compliance_score": { "type": "number" },
          "verifications": { "type": "array", "items": { "type": "string" } },
          "jws_signature": { "type": "string" }
        }
      },
      "Dac7Seller": {
        "type": "object",
        "properties": {
          "freelancer_id": { "type": "string", "format": "uuid" },
          "reporting_year": { "type": "integer" },
          "tin": { "type": "string" },
          "member_state": { "type": "string" },
          "total_consideration_eur": { "type": "number" },
          "number_of_activities": { "type": "integer" },
          "reported_at": { "type": "string", "format": "date-time" }
        }
      }
    }
  },
  "security": [{ "bearerAuth": [] }]
}
