{
  "openapi": "3.1.0",
  "info": {
    "title": "Multabot API",
    "version": "1.0.0",
    "description": "API REST para consultar los datos de un vehículo por patente o VIN: multas, deuda de patente, VTV, RTO, GNC y recalls. Cada consulta corre en segundo plano en todas las fuentes activas y avisa por webhook cuando termina. El acceso requiere una cuenta de empresa habilitada por Multabot.",
    "contact": {
      "name": "Soporte de Multabot",
      "url": "https://multabot.com.ar/contacto",
      "email": "contacto@multabot.com.ar"
    }
  },
  "servers": [
    {
      "url": "https://api.multabot.com.ar",
      "description": "Producción"
    }
  ],
  "externalDocs": {
    "description": "Portal de desarrolladores de Multabot",
    "url": "https://multabot.com.ar/developers"
  },
  "tags": [
    {
      "name": "Consultas",
      "description": "Crear, leer, completar, reintentar y cancelar consultas de un vehículo."
    },
    {
      "name": "Cobertura",
      "description": "Fuentes disponibles y tipos de consulta."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/tasks": {
      "post": {
        "operationId": "createTask",
        "summary": "Crear una consulta",
        "tags": [
          "Consultas"
        ],
        "description": "Crea una consulta para un vehículo. Corre en todas las fuentes activas que cubren el tipo pedido y termina en segundo plano: leé el avance con getTask o esperá el webhook. Las fuentes que necesitan VIN o documento y no los recibieron quedan como skipped y aparecen en warnings. Repetir un external_id devuelve la consulta existente.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTaskRequest"
              },
              "examples": {
                "multas": {
                  "value": {
                    "type": "fines",
                    "country": "ARG",
                    "plate": "AE102KD",
                    "external_id": "op-7781"
                  }
                },
                "recalls": {
                  "value": {
                    "type": "recalls",
                    "country": "ARG",
                    "plate": "AE102KD",
                    "vin": "8AJBA3CD5P1234567"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Consulta creada, en estado processing.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "200": {
            "description": "Ya existía una consulta con ese external_id.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      },
      "get": {
        "operationId": "listTasks",
        "summary": "Listar consultas",
        "tags": [
          "Consultas"
        ],
        "description": "Lista las consultas de la cuenta, de la más nueva a la más vieja.",
        "parameters": [
          {
            "name": "plate",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 12
            }
          },
          {
            "name": "vin",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 17
            }
          },
          {
            "name": "external_id",
            "in": "query",
            "schema": {
              "type": "string",
              "maxLength": 191
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/TaskType"
            }
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Country"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/TaskStatus"
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Una página de consultas.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskPage"
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v1/tasks/{id}": {
      "get": {
        "operationId": "getTask",
        "summary": "Obtener una consulta",
        "tags": [
          "Consultas"
        ],
        "description": "Devuelve la consulta con el resultado de cada fuente. Mientras está en processing, las fuentes se completan a medida que terminan. Los archivos de evidencia traen una url firmada que vence en url_expires_at; cada llamada genera enlaces nuevos.",
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          }
        ],
        "responses": {
          "200": {
            "description": "La consulta.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v1/tasks/{id}/vin": {
      "post": {
        "operationId": "addVinToTask",
        "summary": "Agregar el VIN",
        "description": "Agrega el VIN a una consulta creada sin él y corre las fuentes que se saltearon por falta de VIN. El resultado se suma a la misma consulta con una nueva revision y se envía un nuevo webhook al terminar.",
        "tags": [
          "Consultas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          }
        ],
        "responses": {
          "200": {
            "description": "La consulta actualizada.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "vin"
                ],
                "properties": {
                  "vin": {
                    "$ref": "#/components/schemas/Vin"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks/{id}/retry": {
      "post": {
        "operationId": "retryTask",
        "summary": "Reintentar fuentes sin resultado",
        "description": "Vuelve a correr las fuentes que fallaron. El resultado se suma a la misma consulta con una nueva revision y se envía un nuevo webhook al terminar.",
        "tags": [
          "Consultas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          }
        ],
        "responses": {
          "200": {
            "description": "La consulta actualizada.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v1/tasks/{id}/cancel": {
      "post": {
        "operationId": "cancelTask",
        "summary": "Cancelar una consulta",
        "description": "Cancela una consulta en processing. Las fuentes que no empezaron no se consultan y no se envía webhook.",
        "tags": [
          "Consultas"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/TaskId"
          }
        ],
        "responses": {
          "200": {
            "description": "La consulta actualizada.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Task"
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v1/entities": {
      "get": {
        "operationId": "listEntities",
        "summary": "Listar fuentes",
        "tags": [
          "Cobertura"
        ],
        "description": "Lista las fuentes que consultan las tareas, con los tipos que cubre cada una y los datos que pide. Las fuentes con vin en required_fields solo corren si la consulta tiene VIN.",
        "parameters": [
          {
            "name": "country",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/Country"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/TaskType"
            }
          },
          {
            "name": "active",
            "in": "query",
            "schema": {
              "type": "boolean"
            },
            "description": "true: solo las que corren hoy. false: solo las inactivas."
          }
        ],
        "responses": {
          "200": {
            "description": "Las fuentes.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Entity"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    },
    "/v1/task-types": {
      "get": {
        "operationId": "listTaskTypes",
        "summary": "Listar tipos de consulta",
        "tags": [
          "Cobertura"
        ],
        "description": "Cada tipo de consulta con sus fuentes activas y si el VIN hace falta siempre (always), a veces (some) o nunca (never).",
        "responses": {
          "200": {
            "description": "Los tipos de consulta.",
            "headers": {
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimit"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemaining"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitReset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/TaskTypeCoverage"
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        }
      }
    }
  },
  "webhooks": {
    "taskFinished": {
      "post": {
        "summary": "Consulta terminada",
        "description": "Se envía una vez por revision cuando la consulta termina. El header X-Multabot-Signature es sha256= seguido de HMAC-SHA256 de \"{X-Multabot-Timestamp}.{body}\" con el secreto del webhook. Respondé 2xx; si no, se reintenta.",
        "parameters": [
          {
            "name": "X-Multabot-Event",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Multabot-Delivery",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Multabot-Timestamp",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Multabot-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookPayload"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Recibido."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key"
      }
    },
    "parameters": {
      "TaskId": {
        "name": "id",
        "in": "path",
        "required": true,
        "description": "Id de la consulta.",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      }
    },
    "headers": {
      "RateLimitLimit": {
        "description": "Límite de solicitudes de la ventana actual.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "RateLimitRemaining": {
        "description": "Solicitudes restantes en la ventana actual.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "RateLimitReset": {
        "description": "Segundos hasta el reinicio de la ventana actual.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "RetryAfter": {
        "description": "Segundos que el cliente debe esperar antes de reintentar.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Falta un token Bearer válido.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "NotFound": {
        "description": "No existe la consulta en esta cuenta.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "ValidationError": {
        "description": "Los datos no son válidos o la operación no corresponde al estado de la consulta. El cuerpo puede incluir errors con mensajes por campo (ver ValidationProblem).",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Se alcanzó el límite de solicitudes. Esperá el tiempo indicado y reintentá.",
        "headers": {
          "RateLimit-Limit": {
            "$ref": "#/components/headers/RateLimitLimit"
          },
          "RateLimit-Remaining": {
            "$ref": "#/components/headers/RateLimitRemaining"
          },
          "RateLimit-Reset": {
            "$ref": "#/components/headers/RateLimitReset"
          },
          "Retry-After": {
            "$ref": "#/components/headers/RetryAfter"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Error inesperado del servidor. Reintentá con backoff.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/Problem"
            }
          }
        }
      }
    },
    "schemas": {
      "TaskType": {
        "type": "string",
        "enum": [
          "fines",
          "verification",
          "taxes",
          "recalls"
        ],
        "description": "fines: multas de tránsito. verification: VTV, RTO, ITV y GNC. taxes: deuda de patente. recalls: campañas de seguridad de fábrica (requiere VIN)."
      },
      "Country": {
        "type": "string",
        "enum": [
          "ARG"
        ]
      },
      "TaskStatus": {
        "type": "string",
        "enum": [
          "processing",
          "completed",
          "partial",
          "failed",
          "cancelled"
        ],
        "description": "completed: todas las fuentes respondieron. partial: alguna falló o se salteó. failed: ninguna respondió."
      },
      "RunStatus": {
        "type": "string",
        "enum": [
          "pending",
          "processing",
          "succeeded",
          "failed",
          "skipped",
          "cancelled"
        ]
      },
      "Vin": {
        "type": "string",
        "pattern": "^[A-HJ-NPR-Z0-9]{17}$",
        "examples": [
          "8AJBA3CD5P1234567"
        ]
      },
      "CreateTaskRequest": {
        "type": "object",
        "required": [
          "type",
          "country",
          "plate"
        ],
        "properties": {
          "type": {
            "$ref": "#/components/schemas/TaskType"
          },
          "country": {
            "$ref": "#/components/schemas/Country"
          },
          "plate": {
            "type": "string",
            "minLength": 5,
            "maxLength": 12,
            "description": "Patente. Se quitan espacios y guiones.",
            "examples": [
              "AE102KD"
            ]
          },
          "vin": {
            "$ref": "#/components/schemas/Vin",
            "description": "Opcional, pero sin VIN las fuentes que lo piden no corren."
          },
          "document": {
            "type": "string",
            "maxLength": 30,
            "description": "DNI o CUIT del titular, para las fuentes que lo piden."
          },
          "external_id": {
            "type": "string",
            "maxLength": 191,
            "description": "Tu id para esta consulta. Hace la llamada idempotente y vuelve en el webhook."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "URL HTTPS para el webhook de esta consulta. Por defecto, la configurada en la cuenta."
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "JSON libre que se guarda y se devuelve tal cual."
          }
        }
      },
      "Warning": {
        "type": "object",
        "required": [
          "code",
          "message",
          "entities"
        ],
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "missing_vin",
              "missing_document"
            ]
          },
          "message": {
            "type": "string"
          },
          "entities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "EntityResult": {
        "type": "object",
        "properties": {
          "run_id": {
            "type": "string"
          },
          "runner": {
            "type": "string"
          },
          "entity": {
            "type": "string"
          },
          "province": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/RunStatus"
          },
          "skip_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "missing_vin",
              "missing_document",
              null
            ]
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "data": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Los datos que publicó la fuente. Cada lista files trae objetos con name, path, url y url_expires_at."
          }
        }
      },
      "Task": {
        "type": "object",
        "required": [
          "id",
          "type",
          "country",
          "plate",
          "status",
          "revision",
          "warnings",
          "result",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "$ref": "#/components/schemas/TaskType"
          },
          "country": {
            "$ref": "#/components/schemas/Country"
          },
          "plate": {
            "type": "string"
          },
          "vin": {
            "type": [
              "string",
              "null"
            ]
          },
          "document": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "$ref": "#/components/schemas/TaskStatus"
          },
          "revision": {
            "type": "integer",
            "minimum": 1,
            "description": "Sube con cada add_vin o retry."
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ]
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Warning"
            }
          },
          "result": {
            "type": "object",
            "properties": {
              "summary": {
                "type": "object",
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "pending": {
                    "type": "integer"
                  },
                  "processing": {
                    "type": "integer"
                  },
                  "succeeded": {
                    "type": "integer"
                  },
                  "failed": {
                    "type": "integer"
                  },
                  "skipped": {
                    "type": "integer"
                  },
                  "cancelled": {
                    "type": "integer"
                  }
                }
              },
              "entities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/EntityResult"
                }
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "finished_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "TaskPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Task"
            }
          },
          "links": {
            "type": "object"
          },
          "meta": {
            "type": "object",
            "properties": {
              "current_page": {
                "type": "integer"
              },
              "last_page": {
                "type": "integer"
              },
              "per_page": {
                "type": "integer"
              },
              "total": {
                "type": "integer"
              }
            }
          }
        }
      },
      "Entity": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "runner": {
            "type": "string"
          },
          "country": {
            "$ref": "#/components/schemas/Country"
          },
          "name": {
            "type": "string"
          },
          "authority": {
            "type": [
              "string",
              "null"
            ]
          },
          "province": {
            "type": [
              "string",
              "null"
            ]
          },
          "site_url": {
            "type": [
              "string",
              "null"
            ],
            "format": "uri"
          },
          "task_types": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TaskType"
            }
          },
          "required_fields": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "plate",
                "vin",
                "document"
              ]
            }
          },
          "is_active": {
            "type": "boolean"
          }
        }
      },
      "TaskTypeCoverage": {
        "type": "object",
        "properties": {
          "type": {
            "$ref": "#/components/schemas/TaskType"
          },
          "description": {
            "type": "string"
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "country": {
                  "$ref": "#/components/schemas/Country"
                },
                "active_entities": {
                  "type": "integer"
                },
                "vin_required": {
                  "type": "string",
                  "enum": [
                    "always",
                    "some",
                    "never"
                  ]
                }
              }
            }
          }
        }
      },
      "WebhookPayload": {
        "type": "object",
        "required": [
          "event",
          "delivery_id",
          "revision",
          "task"
        ],
        "properties": {
          "event": {
            "type": "string",
            "enum": [
              "task.completed",
              "task.partial",
              "task.failed"
            ]
          },
          "delivery_id": {
            "type": "string"
          },
          "revision": {
            "type": "integer"
          },
          "task": {
            "$ref": "#/components/schemas/Task"
          }
        }
      },
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string",
            "format": "uri-reference"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "minimum": 400,
            "maximum": 599
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string",
            "format": "uri-reference"
          }
        }
      },
      "ValidationProblem": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Problem"
          },
          {
            "type": "object",
            "properties": {
              "errors": {
                "type": "object",
                "description": "Mensajes por campo.",
                "additionalProperties": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}