---
title: "Grant Contract Gesture"
method: POST
path: "/admin/schools/{school_id}/contracts/{contract_id}/gesture"
tags: ["Admin - Schools"]
---

# Grant Contract Gesture

`POST /admin/schools/{school_id}/contracts/{contract_id}/gesture`

## Request

- Base URL: `https://api.excellence-ai.com` (the document declares no server; this is the origin it was published from)
- URL: `https://api.excellence-ai.com/admin/schools/{school_id}/contracts/{contract_id}/gesture`
- Auth: OAuth 2 (password, token URL `api/login`)

Grant the commercial gesture: +30 days on the contract end date, once.

Same button for everyone, no per-role ceiling: the guard rail is that it
only works once per contract. Anything beyond goes through tech, directly
in the database.

## Path parameters

- `school_id` string, required: The ID of the school
- `contract_id` string, required: The ID of the contract

## Request body

- SchoolContractGestureCreateRequest
  - `reason` string, required

## Response `200`

Successful Response

- SchoolContractResponse
  - `id` string, required
  - `school_id` string, required
  - `contract_type` 'pilot' | 'paid', required
  - `start_date` string, date-time, required
  - `end_date` string, date-time, nullable
  - `billed_students` integer, nullable
  - `expected_teachers_count` integer, nullable
  - `price_per_student_monthly_eur` number, nullable
  - `free_months` number, nullable
  - `launch_guarantee` boolean
  - `launch_guarantee_end_date` string, date-time, nullable
  - `owner_admin_id` string, nullable
  - `owner_name` string, nullable
  - `referent_name` string, nullable
  - `referent_email` string, nullable
  - `referent_role` string, nullable
  - `signed_document_date` string, date-time, nullable
  - `signed_document_url` string, nullable
  - `pennylane_url` string, nullable
  - `notes` string, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `status` 'active' | 'upcoming' | 'ended', required
  - `levels` string[]
  - `billing_rhythm` 'quarterly' | 'annual'
  - `gesture` SchoolContractGestureResponse
    - `id` string, required
    - `contract_id` string, required
    - `days` integer, required
    - `reason` string, required
    - `granted_by_admin_id` string, required
    - `granted_by_name` string, nullable
    - `previous_end_date` string, date-time, nullable
    - `new_end_date` string, date-time, nullable
    - `created_at` string, date-time, required

## Other responses

- `422`: Validation Error

## Changes

> 55 revisions in range; 1 not diffed.

- **2026-10-11** `271be6884523`: 2 breaking, 2 info
  - response property `free_months` list-of-types was widened by adding types `number` to media type `application/json` of response `200`
  - the `free_months/anyOf[subschema #1]/` response's property type changed from `integer` to `number` for status `200`
  - added the optional property `launch_guarantee` to the response with the `200` status
  - added the optional property `launch_guarantee_end_date` to the response with the `200` status
- **2026-10-06** `59dba414f8ae`: 2 info
  - added the optional property `billing_rhythm` to the response with the `200` status
  - added the optional property `levels` to the response with the `200` status

[Operation history](https://skmtc.dev/excellence-ai/apis/excellence-learning/changes/admin/schools/:school_id/contracts/:contract_id/gesture/post.md)

---

[API](https://skmtc.dev/excellence-ai/apis/excellence-learning.md) - [All operations](https://skmtc.dev/excellence-ai/apis/excellence-learning/llms.txt) - [OpenAPI document](https://skmtc.dev/excellence-ai/apis/excellence-learning/revisions/379e4a57dee8?raw)
