{
  "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, 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.com/developers"
    },
    "license": {
      "name": "PROFOYO API Terms",
      "url": "https://profoyo.com/legal/api-terms"
    },
    "termsOfService": "https://profoyo.com/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": "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"
          }
        }
      }
    },
    "/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"
          }
        }
      },
      "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": []
    }
  ]
}
