{"openapi":"3.1.0","info":{"title":"API EduPay","version":"1.0.0-beta","summary":"API pública das escolas no EduPay.","description":"Dá a outros sistemas (ERP, CRM, site, LMS, BI) acesso aos dados de uma escola no EduPay. A chave é criada pela escola em Integrações → Tokens de API e vale só para os dados dela. A API nasce desligada em cada escola e é ligada na mesma tela.\n\nErros em application/problem+json (RFC 9457): decida pelo `code`, que não muda entre versões. Dinheiro em centavos (inteiro) com a moeda ao lado; data e hora em ISO 8601 UTC; datas sem hora (vencimento) em AAAA-MM-DD.\n\nListas: `limit` (1 a 200, padrão 50), `cursor` (o `meta.next_cursor` da página anterior) e `updated_since` (só o que mudou desde a data). Cada permissão (escopo) libera uma área; dados relacionados por `include` pedem a permissão da própria área.\n\nEscritas (POST e PATCH) aceitam o cabeçalho `Idempotency-Key` com um código único por pedido (um UUID, por exemplo): repetir o mesmo pedido com a mesma chave em até 24 h devolve a primeira resposta, com `Idempotent-Replayed: true`, sem gravar de novo. Criar matrícula exige a chave. Só respostas de sucesso ficam guardadas: depois de um erro, corrija o pedido e repita com a mesma chave.\n\nAs rotas do plugin do Moodle (/api/moodle/*) não fazem parte desta especificação e continuam como sempre foram.","x-scopes-note":"x-scopes em cada operação lista a permissão exigida."},"servers":[{"url":"https://edupay.estudiosite.com/api/v1"}],"security":[{"chave":[]}],"tags":[{"name":"Conta","description":"A escola dona da chave.","x-translations":{"en":{"name":"Account","description":"The school that owns the key."},"es":{"name":"Cuenta","description":"La escuela dueña de la clave."}}},{"name":"Catálogo","description":"O que a escola vende (catalog:read).","x-translations":{"en":{"name":"Catalog","description":"What the school sells (catalog:read)."},"es":{"name":"Catálogo","description":"Lo que vende la escuela (catalog:read)."}}},{"name":"Alunos","description":"Cadastro dos alunos (students:read, students:write), resumo financeiro (billing:read) e link de entrada no portal (portal:link).","x-translations":{"en":{"name":"Students","description":"Student records (students:read, students:write), financial summary (billing:read) and portal sign-in link (portal:link)."},"es":{"name":"Alumnos","description":"Registro de los alumnos (students:read, students:write), resumen financiero (billing:read) y enlace de acceso al portal (portal:link)."}}},{"name":"Matrículas","description":"Matrículas e contratos (enrollments:read, enrollments:write).","x-translations":{"en":{"name":"Enrollments","description":"Enrollments and contracts (enrollments:read, enrollments:write)."},"es":{"name":"Matrículas","description":"Matrículas y contratos (enrollments:read, enrollments:write)."}}},{"name":"Cobranças","description":"Parcelas, dados para pagar (billing:read) e 2ª via (billing:write).","x-translations":{"en":{"name":"Billing","description":"Installments, payment details (billing:read) and second copy (billing:write)."},"es":{"name":"Cobros","description":"Cuotas, datos para pagar (billing:read) y segunda copia (billing:write)."}}},{"name":"Avisos automáticos","description":"Endereços que recebem os avisos da escola (webhooks:manage). O formato do aviso está em webhooks → evento.","x-translations":{"en":{"name":"Webhooks","description":"Endpoints that receive the school's webhooks (webhooks:manage). The notification format is under webhooks → evento."},"es":{"name":"Avisos automáticos","description":"Direcciones que reciben los avisos de la escuela (webhooks:manage). El formato del aviso está en webhooks → evento."}}}],"paths":{"/me":{"get":{"operationId":"me","summary":"A escola dona da chave","description":"Dados da escola dona da chave e da própria chave. Qualquer chave válida pode chamar; serve para testar a conexão.","tags":["Conta"],"x-scopes":[],"responses":{"200":{"description":"A escola e a chave.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"},"example":{"data":{"school":{"name":"Colégio Modelo","country":"BR","currency":"BRL","timezone":"America/Sao_Paulo"},"token":{"name":"ERP Financeiro","prefix":"edp_7d2e9f01...","scopes":["students:read","billing:read"],"expires_at":null}}}}},"x-translations":{"en":{"description":"The school and the key."},"es":{"description":"La escuela y la clave."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"The school that owns the key","description":"Details of the school that owns the key and of the key itself. Any valid key can call it; use it to test the connection."},"es":{"summary":"La escuela dueña de la clave","description":"Datos de la escuela dueña de la clave y de la propia clave. Cualquier clave válida puede llamarla; sirve para probar la conexión."}}}},"/openapi.json":{"get":{"operationId":"getOpenApi","summary":"Especificação OpenAPI","description":"Esta especificação, em JSON (OpenAPI 3.1), com o endereço deste servidor. Aberta, sem chave: serve para gerar cliente, importar no Postman ou Insomnia e ler em ferramentas de IA.","tags":["Conta"],"security":[],"responses":{"200":{"description":"A especificação.","content":{"application/json":{"schema":{"type":"object"}}},"x-translations":{"en":{"description":"The specification."},"es":{"description":"La especificación."}}}},"x-translations":{"en":{"summary":"OpenAPI specification","description":"This specification, in JSON (OpenAPI 3.1), with this server's address. Open, no key needed: use it to generate a client, import it into Postman or Insomnia and read it in AI tools."},"es":{"summary":"Especificación OpenAPI","description":"Esta especificación, en JSON (OpenAPI 3.1), con la dirección de este servidor. Abierta, sin clave: sirve para generar un cliente, importar en Postman o Insomnia y leer en herramientas de IA."}}}},"/offerings":{"get":{"operationId":"listOfferings","summary":"Listar cursos e ofertas","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}},{"name":"type","in":"query","schema":{"type":"string","enum":["postgrad","undergrad","school","free_course"]}},{"name":"code","in":"query","description":"Código da oferta, exato.","schema":{"type":"string"},"x-translations":{"en":{"description":"Exact offering code."},"es":{"description":"Código de la oferta, exacto."}}}],"responses":{"200":{"description":"Página de ofertas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferingList"}}},"x-translations":{"en":{"description":"Page of offerings."},"es":{"description":"Página de ofertas."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List courses and offerings"},"es":{"summary":"Listar cursos y ofertas"}}}},"/offerings/{offering}":{"get":{"operationId":"getOffering","summary":"Uma oferta","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"name":"offering","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"A oferta.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Offering"}}}}},"x-translations":{"en":{"description":"The offering."},"es":{"description":"La oferta."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"One offering"},"es":{"summary":"Una oferta"}}}},"/trails":{"get":{"operationId":"listTrails","summary":"Listar trilhas","description":"Trilhas com as ofertas que fazem parte de cada uma, na ordem em que o aluno cursa.","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}}],"responses":{"200":{"description":"Página de trilhas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrailList"}}},"x-translations":{"en":{"description":"Page of tracks."},"es":{"description":"Página de trayectos."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List tracks","description":"Tracks with the offerings that make up each one, in the order the student takes them."},"es":{"summary":"Listar trayectos","description":"Trayectos con las ofertas que forman parte de cada uno, en el orden en que el alumno las cursa."}}}},"/cohorts":{"get":{"operationId":"listCohorts","summary":"Listar turmas","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"status","in":"query","schema":{"type":"string","enum":["open","closed","archived"]}}],"responses":{"200":{"description":"Página de turmas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CohortList"}}},"x-translations":{"en":{"description":"Page of cohorts."},"es":{"description":"Página de grupos."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List cohorts"},"es":{"summary":"Listar grupos"}}}},"/financial-plans":{"get":{"operationId":"listFinancialPlans","summary":"Listar planos de pagamento","description":"Formas de pagamento aceitas, número de parcelas, taxa de matrícula, juros e multa. Os campos de desconto do plano não são devolvidos: hoje eles não são aplicados na cobrança.","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}}],"responses":{"200":{"description":"Página de planos.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinancialPlanList"}}},"x-translations":{"en":{"description":"Page of plans."},"es":{"description":"Página de planes."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List payment plans","description":"Accepted payment methods, number of installments, enrollment fee, interest and late fee. The plan's discount fields are not returned: they are not applied to charges today."},"es":{"summary":"Listar planes de pago","description":"Formas de pago aceptadas, número de cuotas, tasa de matrícula, intereses y multa. Los campos de descuento del plan no se devuelven: hoy no se aplican en el cobro."}}}},"/sales-pages":{"get":{"operationId":"listSalesPages","summary":"Listar páginas de vendas publicadas","description":"Só páginas publicadas, com o link público onde o interessado se matricula e o preço.","tags":["Catálogo"],"x-scopes":["catalog:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"}],"responses":{"200":{"description":"Página de páginas de vendas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesPageList"}}},"x-translations":{"en":{"description":"Page of sales pages."},"es":{"description":"Página de páginas de ventas."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List published sales pages","description":"Only published pages, with the public link where prospects enroll and the price."},"es":{"summary":"Listar páginas de ventas publicadas","description":"Solo páginas publicadas, con el enlace público donde el interesado se matricula y el precio."}}}},"/students":{"get":{"operationId":"listStudents","summary":"Listar alunos","tags":["Alunos"],"x-scopes":["students:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"email","in":"query","description":"E-mail exato, sem diferença de maiúsculas.","schema":{"type":"string"},"x-translations":{"en":{"description":"Exact e-mail, case-insensitive."},"es":{"description":"E-mail exacto, sin distinguir mayúsculas."}}},{"name":"document_number","in":"query","description":"CPF ou documento, com ou sem pontuação.","schema":{"type":"string"},"x-translations":{"en":{"description":"CPF (Brazilian individual taxpayer ID) or other document, with or without punctuation."},"es":{"description":"CPF (documento fiscal de persona física en Brasil) u otro documento, con o sin puntuación."}}},{"name":"external_id","in":"query","description":"Código do aluno no sistema da escola.","schema":{"type":"string"},"x-translations":{"en":{"description":"Student code in the school's system."},"es":{"description":"Código del alumno en el sistema de la escuela."}}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","inactive"]}}],"responses":{"200":{"description":"Página de alunos.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentList"}}},"x-translations":{"en":{"description":"Page of students."},"es":{"description":"Página de alumnos."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List students"},"es":{"summary":"Listar alumnos"}}},"post":{"operationId":"createStudent","summary":"Cadastrar aluno","description":"Cria o aluno e a conta de acesso ao portal, como o cadastro do painel. O login segue a configuração da escola (CPF ou e-mail).","tags":["Alunos"],"x-scopes":["students:write"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentCreateInput"},"example":{"external_id":"ALU-0091","full_name":"Maria Souza","email":"maria@exemplo.com","document_number":"12345678909","phone":"11999990000","address":{"zip_code":"01310-100","line":"Av. Paulista","number":"1000","neighborhood":"Bela Vista","city":"São Paulo","state":"SP","country":"BR"}}}}},"responses":{"201":{"description":"Aluno cadastrado.","headers":{"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Student"}}}}},"x-translations":{"en":{"description":"Student created."},"es":{"description":"Alumno registrado."}}},"400":{"$ref":"#/components/responses/IdempotencyKeyInvalid"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"description":"API desligada, chave sem a permissão (insufficient_scope) ou limite de alunos do plano atingido (student_limit_reached).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Forbidden","status":403,"detail":"O plano da escola permite até 500 alunos, e o limite foi atingido.","code":"student_limit_reached"}}},"x-translations":{"en":{"description":"API turned off, key without the permission (insufficient_scope) or the plan's student limit reached (student_limit_reached)."},"es":{"description":"API desactivada, clave sin el permiso (insufficient_scope) o límite de alumnos del plan alcanzado (student_limit_reached)."}}},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/WriteValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Create student","description":"Creates the student and the portal account, like registration in the panel. The login follows the school's setting (CPF or e-mail)."},"es":{"summary":"Registrar alumno","description":"Crea el alumno y la cuenta de acceso al portal, como el registro del panel. El inicio de sesión sigue la configuración de la escuela (CPF o e-mail)."}}}},"/students/{student}":{"get":{"operationId":"getStudent","summary":"Um aluno","tags":["Alunos"],"x-scopes":["students:read"],"parameters":[{"name":"student","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"O aluno.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Student"}}}}},"x-translations":{"en":{"description":"The student."},"es":{"description":"El alumno."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"One student"},"es":{"summary":"Un alumno"}}},"patch":{"operationId":"updateStudent","summary":"Alterar aluno","description":"Altera só os campos enviados. Se o aluno ainda não tinha conta no portal e o dado de login passa a existir, a conta é criada e o e-mail de boas-vindas sai, como na edição pelo painel.","tags":["Alunos"],"x-scopes":["students:write"],"parameters":[{"name":"student","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudentInput"},"example":{"phone":"11988887777","address":{"number":"1200"}}}}},"responses":{"200":{"description":"Aluno alterado.","headers":{"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Student"}}}}},"x-translations":{"en":{"description":"Student updated."},"es":{"description":"Alumno modificado."}}},"400":{"$ref":"#/components/responses/IdempotencyKeyInvalid"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"$ref":"#/components/responses/IdempotencyInProgress"},"422":{"$ref":"#/components/responses/WriteValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Update student","description":"Changes only the fields sent. If the student did not have a portal account yet and the login data now exists, the account is created and the welcome e-mail goes out, like editing in the panel."},"es":{"summary":"Modificar alumno","description":"Modifica solo los campos enviados. Si el alumno todavía no tenía cuenta en el portal y el dato de inicio de sesión pasa a existir, se crea la cuenta y sale el e-mail de bienvenida, como en la edición por el panel."}}}},"/students/{student}/summary":{"get":{"operationId":"getStudentSummary","summary":"Resumo financeiro do aluno","description":"Soma as parcelas que ainda podem ser pagas em qualquer matrícula do aluno, inclusive multa de matrícula cancelada. O contrato é o da matrícula viva mais recente.","tags":["Alunos"],"x-scopes":["billing:read"],"parameters":[{"name":"student","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"O resumo.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/StudentSummary"}}},"example":{"data":{"student_id":532,"currency":"BRL","open_installments":3,"overdue_installments":1,"amount_due":135000,"amount_overdue":45000,"next_installment":{"id":9813,"due_date":"2026-11-10","amount":45000},"active_enrollments":1,"contract_status":"signed"}}}},"x-translations":{"en":{"description":"The summary."},"es":{"description":"El resumen."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Student financial summary","description":"Adds up the installments that can still be paid in any of the student's enrollments, including the fee from a cancelled enrollment. The contract is the one from the most recent live enrollment."},"es":{"summary":"Resumen financiero del alumno","description":"Suma las cuotas que todavía se pueden pagar en cualquier matrícula del alumno, incluida la multa de una matrícula cancelada. El contrato es el de la matrícula vigente más reciente."}}}},"/students/{student}/portal-link":{"post":{"operationId":"createPortalLink","summary":"Link de entrada no portal do aluno","description":"Gera um link que abre o portal do aluno já conectado, sem senha. Vale 5 minutos e uma vez só: gere na hora do clique. O aluno precisa estar ativo, ter e-mail e conta no portal.","tags":["Alunos"],"x-scopes":["portal:link"],"parameters":[{"name":"student","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"201":{"description":"Link gerado.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PortalLink"}}}}},"x-translations":{"en":{"description":"Link generated."},"es":{"description":"Enlace generado."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Aluno inativo (student_inactive), sem e-mail ou conta no portal (student_without_portal_access), portal sem endereço (portal_not_configured) ou e-mail repetido em outro aluno (portal_link_ambiguous_email).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Conflict","status":409,"detail":"O aluno não tem e-mail ou conta de acesso ao portal.","code":"student_without_portal_access"}}},"x-translations":{"en":{"description":"Student inactive (student_inactive), without an e-mail or portal account (student_without_portal_access), portal without an address (portal_not_configured) or e-mail also used by another student (portal_link_ambiguous_email)."},"es":{"description":"Alumno inactivo (student_inactive), sin e-mail o cuenta en el portal (student_without_portal_access), portal sin dirección (portal_not_configured) o e-mail repetido en otro alumno (portal_link_ambiguous_email)."}}},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Student portal sign-in link","description":"Generates a link that opens the student portal already signed in, without a password. It is valid for 5 minutes and only once: generate it at the moment of the click. The student must be active and have an e-mail and a portal account."},"es":{"summary":"Enlace de acceso al portal del alumno","description":"Genera un enlace que abre el portal del alumno con la sesión ya iniciada, sin contraseña. Vale 5 minutos y una sola vez: genérelo en el momento del clic. El alumno tiene que estar activo y tener e-mail y cuenta en el portal."}}}},"/enrollments":{"get":{"operationId":"listEnrollments","summary":"Listar matrículas","tags":["Matrículas"],"x-scopes":["enrollments:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"$ref":"#/components/parameters/EnrollmentInclude"},{"name":"student_id","in":"query","schema":{"type":"integer"}},{"name":"external_id","in":"query","description":"Código da matrícula no sistema da escola.","schema":{"type":"string"},"x-translations":{"en":{"description":"Enrollment code in the school's system."},"es":{"description":"Código de la matrícula en el sistema de la escuela."}}},{"name":"offering_id","in":"query","schema":{"type":"integer"}},{"name":"trail_id","in":"query","schema":{"type":"integer"}},{"name":"cohort_id","in":"query","schema":{"type":"integer"}},{"name":"status","in":"query","schema":{"type":"string","enum":["pending_contract","pending_payment","active","cancelled","completed"]}}],"responses":{"200":{"description":"Página de matrículas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentList"}}},"x-translations":{"en":{"description":"Page of enrollments."},"es":{"description":"Página de matrículas."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List enrollments"},"es":{"summary":"Listar matrículas"}}},"post":{"operationId":"createEnrollment","summary":"Criar matrícula","description":"Cria a matrícula como o painel: gera as parcelas e o contrato, coloca o aluno no Moodle na hora (quando a turma está ligada ao Moodle) e emite as cobranças que já estão na janela de emissão — cartão na hora; boleto e PIX quando faltam poucos dias para o vencimento. Exige Idempotency-Key. Aceita ?include= como a consulta da matrícula.","tags":["Matrículas"],"x-scopes":["enrollments:write"],"parameters":[{"$ref":"#/components/parameters/IdempotencyKeyRequired"},{"$ref":"#/components/parameters/EnrollmentInclude"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentInput"},"example":{"external_id":"PED-2026-1187","student":{"external_id":"ALU-0091","full_name":"Maria Souza","email":"maria@exemplo.com","document_number":"12345678909","phone":"11999990000"},"offering_id":14,"cohort_id":3,"financial_plan_id":2,"payment_method":"pix"}}}},"responses":{"201":{"description":"Matrícula criada.","headers":{"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Enrollment"}}}}},"x-translations":{"en":{"description":"Enrollment created."},"es":{"description":"Matrícula creada."}}},"400":{"$ref":"#/components/responses/IdempotencyKeyInvalid"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"description":"API desligada, chave sem a permissão (insufficient_scope) ou, com aluno novo, limite de alunos do plano atingido (student_limit_reached).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Forbidden","status":403,"detail":"A chave não tem a permissão necessária: enrollments:write.","code":"insufficient_scope","scopes":["enrollments:write"]}}},"x-translations":{"en":{"description":"API turned off, key without the permission (insufficient_scope) or, with a new student, the plan's student limit reached (student_limit_reached)."},"es":{"description":"API desactivada, clave sin el permiso (insufficient_scope) o, con un alumno nuevo, límite de alumnos del plan alcanzado (student_limit_reached)."}}},"409":{"description":"O aluno já tem matrícula viva no mesmo curso ou trilha (enrollment_conflict, com existing_enrollment_id) ou o pedido com esta Idempotency-Key ainda está em andamento (idempotency_in_progress).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Conflict","status":409,"detail":"O aluno já tem matrícula viva neste curso ou trilha (veja existing_enrollment_id).","code":"enrollment_conflict","existing_enrollment_id":812}}},"x-translations":{"en":{"description":"The student already has a live enrollment in the same course or track (enrollment_conflict, with existing_enrollment_id) or the request with this Idempotency-Key is still in progress (idempotency_in_progress)."},"es":{"description":"El alumno ya tiene una matrícula vigente en el mismo curso o trayecto (enrollment_conflict, con existing_enrollment_id) o la solicitud con esta Idempotency-Key todavía está en curso (idempotency_in_progress)."}}},"422":{"$ref":"#/components/responses/WriteValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Create enrollment","description":"Creates the enrollment like the panel does: generates the installments and the contract, adds the student to Moodle right away (when the cohort is linked to Moodle) and issues the charges that are already inside the issuing window — card right away; boleto and PIX when the due date is a few days away. Requires Idempotency-Key. Accepts ?include= like the enrollment query."},"es":{"summary":"Crear matrícula","description":"Crea la matrícula como el panel: genera las cuotas y el contrato, inscribe al alumno en Moodle en el momento (cuando el grupo está vinculado a Moodle) y emite los cobros que ya están en la ventana de emisión — tarjeta en el momento; boleto y PIX cuando faltan pocos días para el vencimiento. Exige Idempotency-Key. Acepta ?include= como la consulta de la matrícula."}}}},"/enrollments/{enrollment}":{"get":{"operationId":"getEnrollment","summary":"Uma matrícula","tags":["Matrículas"],"x-scopes":["enrollments:read"],"parameters":[{"name":"enrollment","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/EnrollmentInclude"}],"responses":{"200":{"description":"A matrícula.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Enrollment"}}}}},"x-translations":{"en":{"description":"The enrollment."},"es":{"description":"La matrícula."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"One enrollment"},"es":{"summary":"Una matrícula"}}}},"/enrollments/{enrollment}/contract":{"get":{"operationId":"getEnrollmentContract","summary":"Contrato da matrícula","tags":["Matrículas"],"x-scopes":["enrollments:read"],"parameters":[{"name":"enrollment","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"O contrato.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Contract"}}}}},"x-translations":{"en":{"description":"The contract."},"es":{"description":"El contrato."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Enrollment contract"},"es":{"summary":"Contrato de la matrícula"}}}},"/enrollments/{enrollment}/contract/pdf":{"get":{"operationId":"downloadEnrollmentContract","summary":"PDF do contrato","description":"O mesmo PDF que o painel da escola baixa.","tags":["Matrículas"],"x-scopes":["enrollments:read"],"parameters":[{"name":"enrollment","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"O arquivo.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}},"x-translations":{"en":{"description":"The file."},"es":{"description":"El archivo."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Contract PDF","description":"The same PDF that the school panel downloads."},"es":{"summary":"PDF del contrato","description":"El mismo PDF que descarga el panel de la escuela."}}}},"/enrollments/{enrollment}/cancel":{"post":{"operationId":"cancelEnrollment","summary":"Cancelar matrícula","description":"Cancela como o painel, sem multa de rescisão (essa só pelo painel): as parcelas em aberto são canceladas junto com as cobranças no Stripe, o aluno é avisado e sai do Moodle. Boleto ainda dentro da validade não pode ser cancelado no Stripe e continua pagável até vencer: meta.charges_still_payable diz quantos.","tags":["Matrículas"],"x-scopes":["enrollments:write"],"parameters":[{"name":"enrollment","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/IdempotencyKey"},{"$ref":"#/components/parameters/EnrollmentInclude"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrollmentCancelInput"},"example":{"reason":"student_withdrawal"}}}},"responses":{"200":{"description":"Matrícula cancelada.","headers":{"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Enrollment"},"meta":{"type":"object","properties":{"charges_still_payable":{"type":"integer","description":"Boletos que continuam pagáveis até vencer."}}}}}}},"x-translations":{"en":{"description":"Enrollment cancelled."},"es":{"description":"Matrícula cancelada."}}},"400":{"$ref":"#/components/responses/IdempotencyKeyInvalid"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"A matrícula já está cancelada ou concluída (enrollment_not_cancellable).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Conflict","status":409,"detail":"Só matrícula aguardando contrato, aguardando pagamento ou ativa pode ser cancelada.","code":"enrollment_not_cancellable"}}},"x-translations":{"en":{"description":"The enrollment is already cancelled or completed (enrollment_not_cancellable)."},"es":{"description":"La matrícula ya está cancelada o concluida (enrollment_not_cancellable)."}}},"422":{"$ref":"#/components/responses/WriteValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Cancel enrollment","description":"Cancels like the panel, without a termination fee (that one only through the panel): open installments are cancelled along with their charges in Stripe, and the student is notified and removed from Moodle. A boleto that is still valid cannot be cancelled in Stripe and stays payable until it expires: meta.charges_still_payable says how many."},"es":{"summary":"Cancelar matrícula","description":"Cancela como el panel, sin multa por rescisión (esa solo por el panel): las cuotas pendientes se cancelan junto con los cobros en Stripe, el alumno recibe un aviso y sale de Moodle. Un boleto todavía dentro de su validez no se puede cancelar en Stripe y se puede pagar hasta que venza: meta.charges_still_payable dice cuántos."}}}},"/installments":{"get":{"operationId":"listInstallments","summary":"Listar parcelas","tags":["Cobranças"],"x-scopes":["billing:read"],"parameters":[{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"},{"name":"enrollment_id","in":"query","schema":{"type":"integer"}},{"name":"student_id","in":"query","schema":{"type":"integer"}},{"name":"status","in":"query","schema":{"type":"string","enum":["open","paid","overdue","cancelled","waived","outstanding"]}},{"name":"due_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"due_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"paid_from","in":"query","schema":{"type":"string","format":"date"}},{"name":"paid_to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Página de parcelas.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InstallmentList"}}},"x-translations":{"en":{"description":"Page of installments."},"es":{"description":"Página de cuotas."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List installments"},"es":{"summary":"Listar cuotas"}}}},"/installments/{installment}":{"get":{"operationId":"getInstallment","summary":"Uma parcela","description":"Inclui a imagem do QR Code PIX (payment.pix_qr_code_base64), que a lista não traz.","tags":["Cobranças"],"x-scopes":["billing:read"],"parameters":[{"name":"installment","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"A parcela.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Installment"}}}}},"x-translations":{"en":{"description":"The installment."},"es":{"description":"La cuota."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"One installment","description":"Includes the PIX QR Code image (payment.pix_qr_code_base64), which the list does not return."},"es":{"summary":"Una cuota","description":"Incluye la imagen del código QR PIX (payment.pix_qr_code_base64), que la lista no trae."}}}},"/installments/{installment}/second-copy":{"post":{"operationId":"createSecondCopy","summary":"Gerar 2ª via","description":"Gera a 2ª via com novo vencimento, como o painel: a parcela atual é cancelada junto com a cobrança no Stripe e nasce outra (replaces_installment_id aponta a anterior), com boleto ou PIX novo e e-mail ao aluno. O valor não muda pela API.","tags":["Cobranças"],"x-scopes":["billing:write"],"parameters":[{"name":"installment","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecondCopyInput"},"example":{"due_date":"2026-11-20"}}}},"responses":{"201":{"description":"A parcela nova, com os dados para pagar.","headers":{"Idempotent-Replayed":{"$ref":"#/components/headers/Idempotent-Replayed"}},"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Installment"}}}}},"x-translations":{"en":{"description":"The new installment, with the payment details."},"es":{"description":"La cuota nueva, con los datos para pagar."}}},"400":{"$ref":"#/components/responses/IdempotencyKeyInvalid"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"Parcela paga, cancelada ou dispensada (installment_not_payable), boleto atual ainda válido (boleto_still_valid) ou escola sem conta Stripe conectada (gateway_not_connected).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Conflict","status":409,"detail":"O boleto atual ainda está dentro da validade e não pode ser cancelado.","code":"boleto_still_valid"}}},"x-translations":{"en":{"description":"Installment paid, cancelled or waived (installment_not_payable), current boleto still valid (boleto_still_valid) or school without a connected Stripe account (gateway_not_connected)."},"es":{"description":"Cuota pagada, cancelada o dispensada (installment_not_payable), boleto actual todavía válido (boleto_still_valid) o escuela sin cuenta de Stripe conectada (gateway_not_connected)."}}},"422":{"$ref":"#/components/responses/WriteValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"},"502":{"description":"O Stripe recusou ou não respondeu (gateway_error). Com installment_id, a 2ª via foi criada e a cobrança dela sai de novo automaticamente.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Bad Gateway","status":502,"detail":"O Stripe recusou ou não respondeu. Se veio installment_id, a 2ª via foi criada e a cobrança dela sai de novo automaticamente.","code":"gateway_error","installment_id":4521}}},"x-translations":{"en":{"description":"Stripe declined or did not respond (gateway_error). With installment_id, the second copy was created and its charge is issued again automatically."},"es":{"description":"Stripe rechazó o no respondió (gateway_error). Con installment_id, la segunda copia se creó y su cobro sale de nuevo automáticamente."}}}},"x-translations":{"en":{"summary":"Issue second copy","description":"Issues the second copy with a new due date, like the panel: the current installment is cancelled along with its charge in Stripe and a new one is created (replaces_installment_id points to the previous one), with a new boleto or PIX and an e-mail to the student. The amount cannot be changed through the API."},"es":{"summary":"Generar segunda copia","description":"Genera la segunda copia con un nuevo vencimiento, como el panel: la cuota actual se cancela junto con el cobro en Stripe y se crea otra (replaces_installment_id apunta a la anterior), con un boleto o PIX nuevo y un e-mail al alumno. El valor no cambia por la API."}}}},"/webhooks":{"get":{"operationId":"listWebhooks","summary":"Listar endereços de aviso","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"responses":{"200":{"description":"Endereços da escola (sem o segredo).","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}}},"x-translations":{"en":{"description":"The school's endpoints (without the secret)."},"es":{"description":"Direcciones de la escuela (sin el secreto)."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"List webhook endpoints"},"es":{"summary":"Listar direcciones de aviso"}}},"post":{"operationId":"createWebhook","summary":"Cadastrar endereço de aviso","description":"A resposta traz o segredo (secret) uma única vez: guarde-o para conferir a assinatura dos avisos. Até 10 endereços por escola.","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEndpointInput"},"example":{"url":"https://erp.escola.com.br/edupay/avisos","description":"ERP financeiro","events":["installment.paid","installment.overdue"]}}}},"responses":{"201":{"description":"Endereço cadastrado, com o segredo.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpoint"},{"type":"object","properties":{"secret":{"type":"string","example":"whsec_3f9a..."}}}]}}}}},"x-translations":{"en":{"description":"Endpoint created, with the secret."},"es":{"description":"Dirección registrada, con el secreto."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"409":{"description":"Limite de endereços atingido.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}},"x-translations":{"en":{"description":"Endpoint limit reached."},"es":{"description":"Límite de direcciones alcanzado."}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Create webhook endpoint","description":"The response contains the secret (secret) only once: keep it to verify the signature of the notifications. Up to 10 endpoints per school."},"es":{"summary":"Registrar dirección de aviso","description":"La respuesta trae el secreto (secret) una sola vez: guárdelo para verificar la firma de los avisos. Hasta 10 direcciones por escuela."}}}},"/webhooks/{webhook}":{"get":{"operationId":"getWebhook","summary":"Um endereço de aviso","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"parameters":[{"name":"webhook","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"O endereço.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}},"x-translations":{"en":{"description":"The endpoint."},"es":{"description":"La dirección."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"One webhook endpoint"},"es":{"summary":"Una dirección de aviso"}}},"patch":{"operationId":"updateWebhook","summary":"Alterar endereço de aviso","description":"Envie só o que muda. enabled: false pausa; enabled: true religa e zera a contagem de falhas.","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"parameters":[{"name":"webhook","in":"path","required":true,"schema":{"type":"integer"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/WebhookEndpointInput"},{"type":"object","properties":{"enabled":{"type":"boolean"}}}]}}}},"responses":{"200":{"description":"O endereço alterado.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookEndpoint"}}}}},"x-translations":{"en":{"description":"The updated endpoint."},"es":{"description":"La dirección modificada."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Update webhook endpoint","description":"Send only what changes. enabled: false pauses it; enabled: true turns it back on and resets the failure count."},"es":{"summary":"Modificar dirección de aviso","description":"Envíe solo lo que cambia. enabled: false pausa; enabled: true reactiva y pone en cero el conteo de fallas."}}},"delete":{"operationId":"deleteWebhook","summary":"Excluir endereço de aviso","description":"Apaga também o histórico de entregas.","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"parameters":[{"name":"webhook","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"204":{"description":"Excluído.","x-translations":{"en":{"description":"Deleted."},"es":{"description":"Eliminada."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Delete webhook endpoint","description":"Also deletes the delivery history."},"es":{"summary":"Eliminar dirección de aviso","description":"También borra el historial de entregas."}}}},"/webhooks/{webhook}/deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"Histórico de entregas do endereço","description":"Últimos 30 dias, do mais antigo para o mais novo.","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"parameters":[{"name":"webhook","in":"path","required":true,"schema":{"type":"integer"}},{"$ref":"#/components/parameters/Limit"},{"$ref":"#/components/parameters/Cursor"},{"$ref":"#/components/parameters/UpdatedSince"}],"responses":{"200":{"description":"Página de entregas.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}}}},"x-translations":{"en":{"description":"Page of deliveries."},"es":{"description":"Página de entregas."}}},"400":{"$ref":"#/components/responses/InvalidCursor"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Endpoint delivery history","description":"Last 30 days, oldest first."},"es":{"summary":"Historial de entregas de la dirección","description":"Últimos 30 días, del más antiguo al más reciente."}}}},"/webhooks/{webhook}/test":{"post":{"operationId":"testWebhook","summary":"Enviar aviso de teste","description":"Manda um aviso webhook.test ao endereço, numa tentativa só. Funciona mesmo com a API da escola desligada.","tags":["Avisos automáticos"],"x-scopes":["webhooks:manage"],"parameters":[{"name":"webhook","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"202":{"description":"Aviso de teste na fila.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookDelivery"}}}}},"x-translations":{"en":{"description":"Test notification queued."},"es":{"description":"Aviso de prueba en cola."}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"x-translations":{"en":{"summary":"Send test notification","description":"Sends a webhook.test notification to the endpoint, in a single attempt. Works even with the school's API turned off."},"es":{"summary":"Enviar aviso de prueba","description":"Envía un aviso webhook.test a la dirección, en un solo intento. Funciona aunque la API de la escuela esté desactivada."}}}}},"webhooks":{"evento":{"post":{"summary":"Aviso automático que o EduPay envia ao endereço da escola","description":"POST em JSON para cada evento assinado. Cabeçalhos: X-Edupay-Event (tipo), X-Edupay-Event-Id (id do evento, igual em reenvios), X-Edupay-Delivery (id da entrega) e X-Edupay-Signature: t=<unix>,v1=<HMAC-SHA256 de \"t.corpo\" com o segredo>. Confira a assinatura e recuse avisos com mais de 5 minutos. Responda 2xx em até 10 segundos; sem isso, nova tentativa em 1 min, 5 min, 30 min, 2 h, 12 h e 24 h. Depois de 3 dias falhando, o endereço é desligado e o dono da escola recebe e-mail. Um mesmo aviso pode chegar mais de uma vez: ignore id repetido.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookEvent"},"example":{"id":"evt_01jbx7k3m2q9r8s7t6v5w4x3y2","type":"installment.paid","created_at":"2026-10-28T14:30:00Z","api_version":"v1","data":{"installment":{"id":9812,"enrollment_id":1204,"student_id":532,"number":3,"type":"regular","status":"paid","amount":45000,"paid_amount":45000,"currency":"BRL","due_date":"2026-10-30","paid_at":"2026-10-28T14:29:51Z","manually_paid":false,"payment_method":"pix","replaces_installment_id":null,"payment":null},"student":{"id":532,"external_id":"ALU-0091","full_name":"Maria Souza","email":"maria@exemplo.com"}}}}}},"responses":{"200":{"description":"Qualquer resposta 2xx confirma o recebimento."}}}}},"components":{"securitySchemes":{"chave":{"type":"http","scheme":"bearer","description":"Chave da escola, no formato edp_ seguido de 64 caracteres: Authorization: Bearer edp_..."}},"parameters":{"Limit":{"name":"limit","in":"query","description":"Itens por página (1 a 200).","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"x-translations":{"en":{"description":"Items per page (1 to 200)."},"es":{"description":"Elementos por página (1 a 200)."}}},"Cursor":{"name":"cursor","in":"query","description":"O meta.next_cursor da página anterior.","schema":{"type":"string"},"x-translations":{"en":{"description":"The meta.next_cursor of the previous page."},"es":{"description":"El meta.next_cursor de la página anterior."}}},"UpdatedSince":{"name":"updated_since","in":"query","description":"Só registros alterados desde esta data e hora (ISO 8601).","schema":{"type":"string","format":"date-time"},"x-translations":{"en":{"description":"Only records changed since this date and time (ISO 8601)."},"es":{"description":"Solo registros modificados desde esta fecha y hora (ISO 8601)."}}},"EnrollmentInclude":{"name":"include","in":"query","description":"Dados relacionados, separados por vírgula: student (exige students:read), installments (exige billing:read), contract.","schema":{"type":"string","example":"student,installments,contract"},"x-translations":{"en":{"description":"Related data, comma-separated: student (requires students:read), installments (requires billing:read), contract."},"es":{"description":"Datos relacionados, separados por coma: student (exige students:read), installments (exige billing:read), contract."}}},"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":false,"description":"Código único deste pedido (até 255 caracteres visíveis; um UUID serve). Repetir com a mesma chave em 24 h devolve a primeira resposta.","schema":{"type":"string","maxLength":255},"example":"7f1c2a9e-4b1d-4c55-9d0e-2f6b8a1c3e77","x-translations":{"en":{"description":"Unique code for this request (up to 255 visible characters; a UUID works). Repeating with the same key within 24 h returns the first response."},"es":{"description":"Código único de esta solicitud (hasta 255 caracteres visibles; sirve un UUID). Repetir con la misma clave en 24 h devuelve la primera respuesta."}}},"IdempotencyKeyRequired":{"name":"Idempotency-Key","in":"header","required":true,"description":"Código único deste pedido (até 255 caracteres visíveis; um UUID serve). Repetir com a mesma chave em 24 h devolve a primeira resposta.","schema":{"type":"string","maxLength":255},"example":"7f1c2a9e-4b1d-4c55-9d0e-2f6b8a1c3e77","x-translations":{"en":{"description":"Unique code for this request (up to 255 visible characters; a UUID works). Repeating with the same key within 24 h returns the first response."},"es":{"description":"Código único de esta solicitud (hasta 255 caracteres visibles; sirve un UUID). Repetir con la misma clave en 24 h devuelve la primera respuesta."}}}},"headers":{"X-Request-Id":{"description":"Identificador da chamada. Informe ao suporte para localizá-la no registro.","schema":{"type":"string","format":"uuid"}},"X-RateLimit-Limit":{"description":"Chamadas permitidas por minuto para esta chave: 120 em consultas, 30 em escritas.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Chamadas que ainda restam neste minuto.","schema":{"type":"integer"}},"Retry-After":{"description":"Segundos até poder chamar de novo.","schema":{"type":"integer"}},"Idempotent-Replayed":{"description":"Presente (true) quando a resposta é a guardada de um pedido anterior com a mesma Idempotency-Key.","schema":{"type":"string","enum":["true"]}}},"responses":{"Unauthenticated":{"description":"Chave ausente, inválida, vencida ou revogada.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Unauthorized","status":401,"detail":"Chave de acesso ausente, inválida, vencida ou revogada.","code":"unauthenticated"}}},"x-translations":{"en":{"description":"Key missing, invalid, expired or revoked."},"es":{"description":"Clave ausente, inválida, vencida o revocada."}}},"Forbidden":{"description":"API desligada na escola (code api_disabled) ou chave sem a permissão necessária (code insufficient_scope, com a lista em scopes).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Forbidden","status":403,"detail":"A chave não tem a permissão necessária: students:read.","code":"insufficient_scope","scopes":["students:read"]}}},"x-translations":{"en":{"description":"API turned off for the school (code api_disabled) or key without the required permission (code insufficient_scope, with the list in scopes)."},"es":{"description":"API desactivada en la escuela (code api_disabled) o clave sin el permiso necesario (code insufficient_scope, con la lista en scopes)."}}},"NotFound":{"description":"Registro não existe nesta escola.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Not Found","status":404,"detail":"Registro não encontrado.","code":"not_found"}}},"x-translations":{"en":{"description":"The record does not exist in this school."},"es":{"description":"El registro no existe en esta escuela."}}},"InvalidCursor":{"description":"Cursor inválido: recomece a lista sem cursor.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Bad Request","status":400,"detail":"Cursor inválido. Recomece a lista sem o parâmetro cursor.","code":"invalid_cursor"}}},"x-translations":{"en":{"description":"Invalid cursor: restart the list without a cursor."},"es":{"description":"Cursor inválido: reinicie la lista sin cursor."}}},"ValidationFailed":{"description":"Parâmetro inválido (detalhe por campo em errors).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Unprocessable Content","status":422,"detail":"Alguns campos estão inválidos.","code":"validation_failed","errors":{"limit":["O campo limit não pode ser superior a 200."]}}}},"x-translations":{"en":{"description":"Invalid parameter (per-field details in errors)."},"es":{"description":"Parámetro inválido (detalle por campo en errors)."}}},"RateLimited":{"description":"Limite de chamadas atingido.","headers":{"Retry-After":{"$ref":"#/components/headers/Retry-After"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Too Many Requests","status":429,"detail":"Limite de chamadas atingido. Tente de novo depois do tempo indicado em Retry-After.","code":"rate_limited"}}},"x-translations":{"en":{"description":"Rate limit reached."},"es":{"description":"Límite de llamadas alcanzado."}}},"IdempotencyKeyInvalid":{"description":"Idempotency-Key ausente onde é exigida (idempotency_key_required) ou fora do formato (idempotency_key_invalid).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Bad Request","status":400,"detail":"Este pedido exige o cabeçalho Idempotency-Key, com um código único por pedido (por exemplo, um UUID).","code":"idempotency_key_required"}}},"x-translations":{"en":{"description":"Idempotency-Key missing where it is required (idempotency_key_required) or in the wrong format (idempotency_key_invalid)."},"es":{"description":"Idempotency-Key ausente donde se exige (idempotency_key_required) o fuera del formato (idempotency_key_invalid)."}}},"IdempotencyInProgress":{"description":"Outro pedido com a mesma Idempotency-Key ainda está em andamento.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Conflict","status":409,"detail":"Um pedido com esta Idempotency-Key ainda está em andamento. Aguarde alguns segundos e repita.","code":"idempotency_in_progress"}}},"x-translations":{"en":{"description":"Another request with the same Idempotency-Key is still in progress."},"es":{"description":"Otra solicitud con la misma Idempotency-Key todavía está en curso."}}},"WriteValidationFailed":{"description":"Campos inválidos (validation_failed, com o detalhe por campo em errors) ou Idempotency-Key já usada com outros dados (idempotency_key_reused).","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"},"example":{"type":"about:blank","title":"Unprocessable Content","status":422,"detail":"Alguns campos estão inválidos.","code":"validation_failed","errors":{"address.line":["O campo endereço é obrigatório."]}}}},"x-translations":{"en":{"description":"Invalid fields (validation_failed, with per-field details in errors) or Idempotency-Key already used with different data (idempotency_key_reused)."},"es":{"description":"Campos inválidos (validation_failed, con el detalle por campo en errors) o Idempotency-Key ya usada con otros datos (idempotency_key_reused)."}}}},"schemas":{"Problem":{"type":"object","required":["type","title","status","detail","code"],"properties":{"type":{"type":"string","example":"about:blank"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string","description":"Texto para gente ler, no idioma pedido (Accept-Language: pt-BR, en ou es).","x-translations":{"en":{"description":"Text for people to read, in the requested language (Accept-Language: pt-BR, en or es)."},"es":{"description":"Texto para que lo lean las personas, en el idioma pedido (Accept-Language: pt-BR, en o es)."}}},"code":{"type":"string","description":"Estável entre versões. Decida por ele.","enum":["unauthenticated","insufficient_scope","api_disabled","forbidden","not_found","method_not_allowed","conflict","validation_failed","rate_limited","invalid_cursor","bad_request","internal_error","http_error","idempotency_key_required","idempotency_key_invalid","idempotency_key_reused","idempotency_in_progress","student_limit_reached","enrollment_conflict","enrollment_not_cancellable","installment_not_payable","boleto_still_valid","gateway_not_connected","gateway_error","student_inactive","student_without_portal_access","portal_not_configured","portal_link_ambiguous_email"],"x-translations":{"en":{"description":"Stable across versions. Decide by it."},"es":{"description":"Estable entre versiones. Decida por él."}}},"errors":{"type":"object","description":"Só em validation_failed: mensagens por campo.","additionalProperties":{"type":"array","items":{"type":"string"}},"x-translations":{"en":{"description":"Only in validation_failed: messages per field."},"es":{"description":"Solo en validation_failed: mensajes por campo."}}},"scopes":{"type":"array","description":"Só em insufficient_scope: permissões que faltam.","items":{"type":"string"},"x-translations":{"en":{"description":"Only in insufficient_scope: the missing permissions."},"es":{"description":"Solo en insufficient_scope: permisos que faltan."}}},"request_id":{"type":"string","format":"uuid"}}},"ListMeta":{"type":"object","properties":{"next_cursor":{"type":["string","null"],"description":"Passe em cursor para a próxima página. Nulo na última.","x-translations":{"en":{"description":"Pass it in cursor for the next page. Null on the last page."},"es":{"description":"Páselo en cursor para la página siguiente. Nulo en la última."}}},"has_more":{"type":"boolean"}}},"Money":{"type":["integer","null"],"description":"Valor em centavos (45000 = 450,00), na moeda do campo currency.","x-translations":{"en":{"description":"Amount in cents (45000 = 450.00), in the currency of the currency field."},"es":{"description":"Valor en centavos (45000 = 450,00), en la moneda del campo currency."}}},"MeResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"school":{"type":"object","properties":{"name":{"type":"string"},"country":{"type":["string","null"],"description":"Código do país (ISO 3166-1 alfa-2)."},"currency":{"type":"string","description":"Moeda da escola (ISO 4217)."},"timezone":{"type":["string","null"],"description":"Fuso da escola, só para exibição. Datas da API vêm em UTC."}}},"token":{"type":"object","properties":{"name":{"type":"string"},"prefix":{"type":"string","description":"Início da chave, para reconhecê-la sem expor o resto."},"scopes":{"type":"array","items":{"type":"string"}},"expires_at":{"type":["string","null"],"format":"date-time"}}}}}}},"Offering":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":["string","null"]},"type":{"type":"string","enum":["postgrad","undergrad","school","free_course"]},"modality":{"type":["string","null"],"enum":["online","presential","hybrid",null]},"workload_hours":{"type":["integer","null"]},"duration_months":{"type":["integer","null"]},"base_price":{"$ref":"#/components/schemas/Money"},"currency":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"moodle_course_id":{"type":["integer","string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Trail":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":["string","null"]},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["active","inactive"]},"offerings":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"code":{"type":["string","null"]},"name":{"type":"string"},"order":{"type":"integer"}}}},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Cohort":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"intake_period":{"type":["string","null"]},"start_date":{"type":["string","null"],"format":"date"},"end_date":{"type":["string","null"],"format":"date"},"is_default":{"type":"boolean"},"status":{"type":"string","enum":["open","closed","archived"]},"moodle_cohort_id":{"type":["integer","string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"FinancialPlan":{"type":"object","properties":{"id":{"type":"integer"},"name":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"enrollment_fee":{"$ref":"#/components/schemas/Money"},"currency":{"type":"string"},"payment_methods":{"type":"object","properties":{"boleto":{"$ref":"#/components/schemas/PlanMethod"},"pix":{"$ref":"#/components/schemas/PlanMethod"},"credit_card":{"type":"object","properties":{"accepted":{"type":"boolean"},"max_installments":{"type":["integer","null"]},"interest_free_installments":{"type":["integer","null"]}}}}},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"PlanMethod":{"type":"object","properties":{"accepted":{"type":"boolean"},"installments":{"type":["integer","null"]},"due_day":{"type":["integer","null"],"description":"Dia do mês do vencimento.","x-translations":{"en":{"description":"Day of the month the payment is due."},"es":{"description":"Día del mes del vencimiento."}}},"interest_rate_daily_percent":{"type":["number","null"],"description":"Juros por dia de atraso, em %.","x-translations":{"en":{"description":"Interest per day late, in %."},"es":{"description":"Intereses por día de atraso, en %."}}},"late_fee_percent":{"type":["number","null"],"description":"Multa por atraso, em %.","x-translations":{"en":{"description":"Late fee, in %."},"es":{"description":"Multa por atraso, en %."}}}}},"SalesPage":{"type":"object","properties":{"id":{"type":"integer"},"title":{"type":"string"},"slug":{"type":"string"},"url":{"type":["string","null"],"format":"uri","description":"Link público da página. Nulo se a escola não configurou o portal.","x-translations":{"en":{"description":"Public link of the page. Null if the school has not set up the portal."},"es":{"description":"Enlace público de la página. Nulo si la escuela no configuró el portal."}}},"status":{"type":"string","enum":["catalog","dashboard","catalog_dashboard"],"description":"catalog: vitrine do portal; dashboard: painel do aluno; catalog_dashboard: os dois.","x-translations":{"en":{"description":"catalog: portal storefront; dashboard: student dashboard; catalog_dashboard: both."},"es":{"description":"catalog: vitrina del portal; dashboard: panel del alumno; catalog_dashboard: los dos."}}},"price":{"type":["integer","null"],"description":"Em centavos. O mesmo preço exibido na página e cobrado na matrícula por ela: o da página ou, sem ele, o do curso (ou a soma das ofertas da trilha).","x-translations":{"en":{"description":"In cents. The same price shown on the page and charged for enrollments made through it: the page's price or, without one, the course price (or the sum of the track's offerings)."},"es":{"description":"En centavos. El mismo precio mostrado en la página y cobrado en la matrícula hecha por ella: el de la página o, sin él, el del curso (o la suma de las ofertas del trayecto)."}}},"currency":{"type":"string"},"product":{"$ref":"#/components/schemas/ProductRef"},"cohort_id":{"type":["integer","null"]},"financial_plan_id":{"type":["integer","null"]},"published_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"ProductRef":{"type":"object","properties":{"type":{"type":["string","null"],"enum":["offering","trail",null]},"id":{"type":["integer","null"]},"name":{"type":["string","null"]}}},"Student":{"type":"object","properties":{"id":{"type":"integer"},"external_id":{"type":["string","null"],"description":"Código do aluno no sistema da escola.","x-translations":{"en":{"description":"Student code in the school's system."},"es":{"description":"Código del alumno en el sistema de la escuela."}}},"full_name":{"type":"string"},"email":{"type":["string","null"]},"phone":{"type":["string","null"]},"document_number":{"type":["string","null"]},"birth_date":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["active","inactive"]},"address":{"type":"object","properties":{"zip_code":{"type":["string","null"]},"line":{"type":["string","null"]},"number":{"type":["string","null"]},"complement":{"type":["string","null"]},"neighborhood":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"country":{"type":["string","null"]}}},"moodle_user_id":{"type":["integer","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"StudentInput":{"type":"object","description":"Os campos obrigatórios seguem a configuração da escola (CPF, telefone e endereço podem ser exigidos; e-mail é exigido quando o login do aluno é o e-mail). No PATCH, envie só o que muda.","properties":{"external_id":{"type":["string","null"],"maxLength":100,"description":"Código do aluno no sistema da escola. Único na escola.","x-translations":{"en":{"description":"Student code in the school's system. Unique within the school."},"es":{"description":"Código del alumno en el sistema de la escuela. Único en la escuela."}}},"full_name":{"type":"string","maxLength":255},"email":{"type":["string","null"],"format":"email"},"phone":{"type":["string","null"],"maxLength":30},"document_number":{"type":["string","null"],"maxLength":20,"description":"CPF (conferido quando a escola liga a validação). Único na escola.","x-translations":{"en":{"description":"CPF (checked when the school turns on validation). Unique within the school."},"es":{"description":"CPF (verificado cuando la escuela activa la validación). Único en la escuela."}}},"birth_date":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["active","inactive"],"default":"active"},"address":{"type":"object","properties":{"zip_code":{"type":["string","null"]},"line":{"type":["string","null"]},"number":{"type":["string","null"]},"complement":{"type":["string","null"]},"neighborhood":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"country":{"type":["string","null"]}}}},"x-translations":{"en":{"description":"Required fields follow the school's settings (CPF, phone and address may be required; e-mail is required when the student signs in with their e-mail). In PATCH, send only what changes."},"es":{"description":"Los campos obligatorios siguen la configuración de la escuela (se pueden exigir CPF, teléfono y dirección; el e-mail se exige cuando el inicio de sesión del alumno es el e-mail). En el PATCH, envíe solo lo que cambia."}}},"StudentCreateInput":{"type":"object","description":"Aluno novo. Os campos obrigatórios seguem a configuração da escola (CPF, telefone e endereço podem ser exigidos; e-mail é exigido quando o login do aluno é o e-mail).","properties":{"external_id":{"type":["string","null"],"maxLength":100,"description":"Código do aluno no sistema da escola. Único na escola.","x-translations":{"en":{"description":"Student code in the school's system. Unique within the school."},"es":{"description":"Código del alumno en el sistema de la escuela. Único en la escuela."}}},"full_name":{"type":"string","maxLength":255},"email":{"type":["string","null"],"format":"email"},"phone":{"type":["string","null"],"maxLength":30},"document_number":{"type":["string","null"],"maxLength":20,"description":"CPF (conferido quando a escola liga a validação). Único na escola.","x-translations":{"en":{"description":"CPF (checked when the school turns on validation). Unique within the school."},"es":{"description":"CPF (verificado cuando la escuela activa la validación). Único en la escuela."}}},"birth_date":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["active","inactive"],"default":"active"},"address":{"type":"object","properties":{"zip_code":{"type":["string","null"]},"line":{"type":["string","null"]},"number":{"type":["string","null"]},"complement":{"type":["string","null"]},"neighborhood":{"type":["string","null"]},"city":{"type":["string","null"]},"state":{"type":["string","null"]},"country":{"type":["string","null"]}}},"send_welcome_email":{"type":"boolean","default":true,"description":"Envia ao aluno o e-mail com login e senha temporária do portal. Com false, a conta é criada sem e-mail (use o link de entrada ou o \"esqueci a senha\").","x-translations":{"en":{"description":"Sends the student the e-mail with the portal login and temporary password. With false, the account is created without the e-mail (use the sign-in link or \"forgot password\")."},"es":{"description":"Envía al alumno el e-mail con el usuario y la contraseña temporal del portal. Con false, la cuenta se crea sin e-mail (use el enlace de acceso o \"Olvidé mi contraseña\")."}}}},"required":["full_name"],"x-translations":{"en":{"description":"New student. Required fields follow the school's settings (CPF, phone and address may be required; e-mail is required when the student signs in with their e-mail)."},"es":{"description":"Alumno nuevo. Los campos obligatorios siguen la configuración de la escuela (se pueden exigir CPF, teléfono y dirección; el e-mail se exige cuando el inicio de sesión del alumno es el e-mail)."}}},"EnrollmentInput":{"type":"object","description":"Informe student_id OU student (aluno novo), e offering_id OU trail_id. Curso, trilha e plano precisam estar ativos e a turma, aberta. Valores em centavos.","required":["financial_plan_id","payment_method"],"properties":{"external_id":{"type":["string","null"],"maxLength":100,"description":"Código da matrícula no sistema da escola. Único na escola.","x-translations":{"en":{"description":"Enrollment code in the school's system. Unique within the school."},"es":{"description":"Código de la matrícula en el sistema de la escuela. Único en la escuela."}}},"student_id":{"type":"integer"},"student":{"$ref":"#/components/schemas/StudentCreateInput"},"offering_id":{"type":"integer"},"trail_id":{"type":"integer"},"cohort_id":{"type":["integer","null"],"description":"Turma. Ligada a uma turma do Moodle, o aluno entra no Moodle na hora, como na matrícula pelo painel.","x-translations":{"en":{"description":"Cohort. If it is linked to a Moodle cohort, the student joins Moodle right away, as with an enrollment made in the panel."},"es":{"description":"Grupo. Si está vinculado a una cohorte de Moodle, el alumno entra a Moodle en el momento, como en la matrícula por el panel."}}},"financial_plan_id":{"type":"integer"},"payment_method":{"type":"string","enum":["boleto","pix","credit_card"],"description":"Precisa ser aceita pelo plano e pela conta Stripe da escola.","x-translations":{"en":{"description":"Must be accepted by the plan and by the school's Stripe account."},"es":{"description":"Tiene que ser aceptada por el plan y por la cuenta de Stripe de la escuela."}}},"contract_template_id":{"type":["integer","null"],"description":"Modelo de contrato. Com assinatura exigida, a matrícula nasce aguardando contrato.","x-translations":{"en":{"description":"Contract template. When a signature is required, the enrollment starts as awaiting contract."},"es":{"description":"Modelo de contrato. Si exige firma, la matrícula se crea esperando contrato."}}},"base_value":{"type":["integer","null"],"minimum":0,"description":"Valor do curso em centavos. Sem ele, vale o preço do curso (ou a soma dos cursos da trilha).","x-translations":{"en":{"description":"Course amount in cents. Without it, the course price applies (or the sum of the track's courses)."},"es":{"description":"Valor del curso en centavos. Sin él, vale el precio del curso (o la suma de los cursos del trayecto)."}}},"enrollment_fee":{"type":["integer","null"],"minimum":0,"description":"Taxa de matrícula em centavos. Sem ela, vale a do plano.","x-translations":{"en":{"description":"Enrollment fee in cents. Without it, the plan's fee applies."},"es":{"description":"Tasa de matrícula en centavos. Sin ella, vale la del plan."}}},"billing_start_date":{"type":["string","null"],"format":"date","description":"Início da cobrança (AAAA-MM-DD).","x-translations":{"en":{"description":"Billing start date (YYYY-MM-DD)."},"es":{"description":"Inicio del cobro (AAAA-MM-DD)."}}},"billing_due_day":{"type":["integer","null"],"minimum":1,"maximum":28,"description":"Dia de vencimento das parcelas.","x-translations":{"en":{"description":"Due day of the installments."},"es":{"description":"Día de vencimiento de las cuotas."}}}},"x-translations":{"en":{"description":"Provide student_id OR student (new student), and offering_id OR trail_id. Course, track and plan must be active and the cohort must be open. Amounts in cents."},"es":{"description":"Informe student_id O student (alumno nuevo), y offering_id O trail_id. El curso, el trayecto y el plan tienen que estar activos, y el grupo, abierto. Valores en centavos."}}},"EnrollmentCancelInput":{"type":"object","properties":{"reason":{"type":["string","null"],"enum":["student_withdrawal","transfer","default","administrative",null],"description":"Desistência do aluno, transferência, inadimplência ou decisão administrativa.","x-translations":{"en":{"description":"Student withdrawal, transfer, default (non-payment) or administrative decision."},"es":{"description":"Desistimiento del alumno, traslado, morosidad o decisión administrativa."}}}}},"SecondCopyInput":{"type":"object","properties":{"due_date":{"type":["string","null"],"format":"date","description":"Novo vencimento (AAAA-MM-DD, de hoje em diante no fuso da escola). Sem ele, vence em 3 dias.","x-translations":{"en":{"description":"New due date (YYYY-MM-DD, today or later in the school's time zone). Without it, it is due in 3 days."},"es":{"description":"Nuevo vencimiento (AAAA-MM-DD, de hoy en adelante en la zona horaria de la escuela). Sin él, vence en 3 días."}}}}},"PortalLink":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Abre o portal já com o aluno conectado. Uso único.","x-translations":{"en":{"description":"Opens the portal with the student already signed in. Single use."},"es":{"description":"Abre el portal con la sesión del alumno ya iniciada. Uso único."}}},"expires_at":{"type":"string","format":"date-time","description":"5 minutos depois de gerado.","x-translations":{"en":{"description":"5 minutes after it is generated."},"es":{"description":"5 minutos después de generado."}}}}},"StudentSummary":{"type":"object","properties":{"student_id":{"type":"integer"},"currency":{"type":"string"},"open_installments":{"type":"integer","description":"Parcelas que ainda podem ser pagas (open, overdue, outstanding).","x-translations":{"en":{"description":"Installments that can still be paid (open, overdue, outstanding)."},"es":{"description":"Cuotas que todavía se pueden pagar (open, overdue, outstanding)."}}},"overdue_installments":{"type":"integer"},"amount_due":{"$ref":"#/components/schemas/Money"},"amount_overdue":{"$ref":"#/components/schemas/Money"},"next_installment":{"type":["object","null"],"properties":{"id":{"type":"integer"},"due_date":{"type":"string","format":"date"},"amount":{"$ref":"#/components/schemas/Money"}}},"active_enrollments":{"type":"integer"},"contract_status":{"type":["string","null"],"enum":["pending","upload_pending","signed","rejected","expired",null]}}},"Enrollment":{"type":"object","properties":{"id":{"type":"integer"},"external_id":{"type":["string","null"],"description":"Código da matrícula no sistema da escola.","x-translations":{"en":{"description":"Enrollment code in the school's system."},"es":{"description":"Código de la matrícula en el sistema de la escuela."}}},"number":{"type":"string"},"status":{"type":"string","enum":["pending_contract","pending_payment","active","cancelled","completed"]},"student_id":{"type":"integer"},"product":{"$ref":"#/components/schemas/ProductRef"},"cohort_id":{"type":["integer","null"]},"financial_plan_id":{"type":["integer","null"]},"payment_method":{"type":"string","enum":["boleto","pix","credit_card"]},"base_value":{"$ref":"#/components/schemas/Money"},"enrollment_fee":{"$ref":"#/components/schemas/Money"},"currency":{"type":"string"},"billing":{"type":"object","properties":{"start_date":{"type":["string","null"],"format":"date"},"due_day":{"type":["integer","null"]}}},"moodle_sync_status":{"type":["string","null"]},"enrolled_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"cancelled_at":{"type":["string","null"],"format":"date-time"},"cancellation_reason":{"type":["string","null"]},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"},"student":{"$ref":"#/components/schemas/Student","description":"Só com include=student.","x-translations":{"en":{"description":"Only with include=student."},"es":{"description":"Solo con include=student."}}},"installments":{"type":"array","items":{"$ref":"#/components/schemas/Installment"},"description":"Só com include=installments.","x-translations":{"en":{"description":"Only with include=installments."},"es":{"description":"Solo con include=installments."}}},"contract":{"oneOf":[{"$ref":"#/components/schemas/Contract"},{"type":"null"}],"description":"Só com include=contract.","x-translations":{"en":{"description":"Only with include=contract."},"es":{"description":"Solo con include=contract."}}}}},"Contract":{"type":"object","properties":{"enrollment_id":{"type":"integer"},"status":{"type":"string","enum":["pending","upload_pending","signed","rejected","expired"]},"signature_method":{"type":"string","enum":["clickwrap","digital","physical"]},"signed_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"uploaded_at":{"type":["string","null"],"format":"date-time"},"pdf_url":{"type":"string","format":"uri","description":"Baixe com a mesma chave (enrollments:read).","x-translations":{"en":{"description":"Download it with the same key (enrollments:read)."},"es":{"description":"Descárguelo con la misma clave (enrollments:read)."}}},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Installment":{"type":"object","properties":{"id":{"type":"integer"},"enrollment_id":{"type":"integer"},"student_id":{"type":["integer","null"]},"number":{"type":"integer"},"type":{"type":"string","enum":["enrollment_fee","regular","penalty"]},"status":{"type":"string","enum":["open","paid","overdue","cancelled","waived","outstanding"]},"amount":{"$ref":"#/components/schemas/Money"},"paid_amount":{"$ref":"#/components/schemas/Money"},"currency":{"type":"string"},"due_date":{"type":"string","format":"date"},"paid_at":{"type":["string","null"],"format":"date-time"},"manually_paid":{"type":"boolean"},"payment_method":{"type":["string","null"],"enum":["boleto","pix","credit_card",null]},"replaces_installment_id":{"type":["integer","null"],"description":"2ª via: a parcela que esta substitui (a anterior fica cancelada).","x-translations":{"en":{"description":"Second copy: the installment this one replaces (the previous one is cancelled)."},"es":{"description":"Segunda copia: la cuota que esta reemplaza (la anterior queda cancelada)."}}},"payment":{"oneOf":[{"$ref":"#/components/schemas/Payment"},{"type":"null"}],"description":"Nulo quando a parcela não pode mais ser paga ou a cobrança foi cancelada.","x-translations":{"en":{"description":"Null when the installment can no longer be paid or the charge was cancelled."},"es":{"description":"Nulo cuando la cuota ya no se puede pagar o el cobro fue cancelado."}}},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"Payment":{"type":"object","properties":{"barcode":{"type":["string","null"],"description":"Linha digitável do boleto.","x-translations":{"en":{"description":"Boleto digitable line."},"es":{"description":"Línea digitable del boleto."}}},"boleto_url":{"type":["string","null"],"format":"uri"},"pix_copy_paste":{"type":["string","null"],"description":"PIX copia e cola.","x-translations":{"en":{"description":"PIX copy-and-paste code."},"es":{"description":"PIX copiar y pegar."}}},"pix_qr_code_base64":{"type":["string","null"],"description":"Imagem do QR Code PIX. Só no detalhe da parcela.","x-translations":{"en":{"description":"PIX QR Code image. Only in the installment detail."},"es":{"description":"Imagen del código QR PIX. Solo en el detalle de la cuota."}}},"payment_url":{"type":["string","null"],"format":"uri","description":"Link de pagamento (cartão).","x-translations":{"en":{"description":"Payment link (card)."},"es":{"description":"Enlace de pago (tarjeta)."}}},"expires_at":{"type":["string","null"],"format":"date-time"}}},"OfferingList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Offering"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"TrailList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Trail"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"CohortList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Cohort"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"FinancialPlanList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FinancialPlan"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"SalesPageList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SalesPage"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"StudentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Student"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"EnrollmentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Enrollment"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"InstallmentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Installment"}},"meta":{"$ref":"#/components/schemas/ListMeta"}}},"WebhookEventType":{"type":"string","description":"student.created/updated: cadastro do aluno. enrollment.created/activated/cancelled/completed: matrícula. enrollment.suspended/reactivated: acesso ao Moodle bloqueado por atraso e liberado. contract.signed: contrato assinado. installment.charge_issued/charge_cancelled: boleto, PIX ou link de cartão emitido ou cancelado. installment.paid/overdue: parcela paga ou vencida. webhook.test: botão de teste.","enum":["student.created","student.updated","enrollment.created","enrollment.activated","enrollment.suspended","enrollment.reactivated","enrollment.cancelled","enrollment.completed","contract.signed","installment.charge_issued","installment.charge_cancelled","installment.paid","installment.overdue","webhook.test"],"x-translations":{"en":{"description":"student.created/updated: student record. enrollment.created/activated/cancelled/completed: enrollment. enrollment.suspended/reactivated: Moodle access blocked for late payment and restored. contract.signed: contract signed. installment.charge_issued/charge_cancelled: boleto, PIX or card link issued or cancelled. installment.paid/overdue: installment paid or overdue. webhook.test: test button."},"es":{"description":"student.created/updated: registro del alumno. enrollment.created/activated/cancelled/completed: matrícula. enrollment.suspended/reactivated: acceso a Moodle bloqueado por atraso y liberado. contract.signed: contrato firmado. installment.charge_issued/charge_cancelled: boleto, PIX o enlace de tarjeta emitido o cancelado. installment.paid/overdue: cuota pagada o vencida. webhook.test: botón de prueba."}}},"WebhookEvent":{"type":"object","required":["id","type","created_at","api_version","data"],"properties":{"id":{"type":"string","description":"evt_..., igual em todas as entregas e reenvios do mesmo evento.","x-translations":{"en":{"description":"evt_..., the same in every delivery and resend of the same event."},"es":{"description":"evt_..., igual en todas las entregas y reenvíos del mismo evento."}}},"type":{"$ref":"#/components/schemas/WebhookEventType"},"created_at":{"type":"string","format":"date-time"},"api_version":{"type":"string","example":"v1"},"data":{"type":"object","description":"Os mesmos formatos da API: student (aluno), enrollment (matrícula), contract (contrato) ou installment (parcela), e student com id, external_id, full_name e email nos avisos de matrícula, contrato e parcela.","properties":{"student":{"type":"object"},"enrollment":{"$ref":"#/components/schemas/Enrollment"},"contract":{"$ref":"#/components/schemas/Contract"},"installment":{"$ref":"#/components/schemas/Installment"}},"x-translations":{"en":{"description":"The same formats as the API: student, enrollment, contract or installment, plus student with id, external_id, full_name and email in enrollment, contract and installment notifications."},"es":{"description":"Los mismos formatos de la API: student (alumno), enrollment (matrícula), contract (contrato) o installment (cuota), y student con id, external_id, full_name y email en los avisos de matrícula, contrato y cuota."}}}}},"WebhookEndpointInput":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"Precisa ser https e apontar para endereço público.","x-translations":{"en":{"description":"Must be https and point to a public address."},"es":{"description":"Tiene que ser https y apuntar a una dirección pública."}}},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"},"description":"Eventos assinados (WebhookEventType) ou [\"*\"] para todos.","x-translations":{"en":{"description":"Subscribed events (WebhookEventType) or [\"*\"] for all."},"es":{"description":"Eventos suscritos (WebhookEventType) o [\"*\"] para todos."}}}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string"}},"enabled":{"type":"boolean"},"disabled_reason":{"type":["string","null"],"enum":["failing","paused",null],"description":"failing: desligado após 3 dias falhando; paused: pausado pela escola.","x-translations":{"en":{"description":"failing: turned off after 3 days of failures; paused: paused by the school."},"es":{"description":"failing: desactivado después de 3 días fallando; paused: pausado por la escuela."}}},"failing_since":{"type":["string","null"],"format":"date-time"},"last_success_at":{"type":["string","null"],"format":"date-time"},"last_failure_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"},"updated_at":{"type":["string","null"],"format":"date-time"}}},"WebhookDelivery":{"type":"object","properties":{"id":{"type":"integer"},"event_id":{"type":"string"},"event_type":{"$ref":"#/components/schemas/WebhookEventType"},"status":{"type":"string","enum":["pending","queued","retrying","succeeded","failed"]},"attempts":{"type":"integer"},"response_status":{"type":["integer","null"]},"response_ms":{"type":["integer","null"]},"error":{"type":["string","null"]},"next_attempt_at":{"type":["string","null"],"format":"date-time"},"last_attempt_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":["string","null"],"format":"date-time"}}}}}}