# Check a registration without registering the student

- Endpoint: `POST /v1/student/check`
- Production: `https://api.main-team.org/v1/student/check`
- Sandbox: `https://apisnd.main-team.org/v1/student/check`
- Operation: `checkStudentRegistration` (Students)
- Authentication: `Authorization: Bearer <token>`, a short-lived token you sign with your API key and secret
- Permission: `student/create:$org:$ID`

## Description

Runs the checks `registerStudent` makes before it creates anything, on the same body without `password`, and tells you what they found. Nothing is created or changed and no username is issued, so sending it any number of times has no effect. Use it to validate a batch before you register it.

**The body** follows `registerStudent`’s rules, and one that breaks a rule is refused the same way, with `400`: a missing or malformed field, `null` for `phone` or `activatedPlatformsThisSeason`, or a property the operation does not accept, `password` included.

**The answer is `200` whatever the lookups found.** `data.valid` is `true` when the registration would pass every check made here:
- `data.duplicate.sameAccount` is `true` when one of your students already has this email address, and `data.duplicate.studentId` is that student’s `_id`: `registerStudent` would answer `409`. Nothing else is looked up then, as registration does not look further either.
- `data.problems` lists every `country`, `grade`, `city` and `school` that matches nothing, each as `{ field, message }` with the message `registerStudent` would answer `400` with, where registration names only the first. A `city` or `school` named inside a country or city that matched nothing is not looked up, so fix the field above it first. A country whose students cannot be given a username is listed as well.
- `data.resolved` has the `_id` each of the four resolved to, what registration would store, or `null`.

**Only your own students are checked for the email address.** An address a student on another account holds is not looked for and not reported, so `valid: true` is not a promise: `registerStudent` still answers `409` for such an address, without saying whose it is. Nor can the check foresee a student registered, or reference data changed, between the check and the registration.

## Request body

Required fields: `firstName`, `lastName`, `birth`, `sex`, `email`, `country`, `grade`, `school`, `city`.

```json
{
  "firstName": "Jane",
  "lastName": "Doe",
  "birth": "14/05/2008",
  "sex": "f",
  "email": "jane.doe@example.com",
  "email2": "<email2>",
  "phone": "+1 555 0100",
  "country": "6650a1b2c3d4e5f6a7b8c9d1",
  "grade": "10",
  "school": "Springfield High School",
  "city": "Springfield",
  "activatedPlatformsThisSeason": [
    "common"
  ]
}
```

## Response

`200` Success: `message` is "Registration checked. Nothing was created.".

```json
{
  "success": true,
  "message": "Registration checked. Nothing was created.",
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 57,
    "totalPages": 3
  },
  "data": {
    "valid": false,
    "problems": [
      {
        "field": "school",
        "message": "school is not a known school. This API does not create reference data."
      }
    ],
    "resolved": {
      "city": "6650a1b2c3d4e5f6a7b8c9d2",
      "country": "6650a1b2c3d4e5f6a7b8c9d1",
      "grade": "6650a1b2c3d4e5f6a7b8c9d4",
      "school": null
    },
    "duplicate": {
      "sameAccount": false
    }
  }
}
```

## Errors

| Status | Code | When |
| --- | --- | --- |
| 400 | [`bad_request`](https://hub.main-team.org/api/errors#bad_request) | The body is not valid JSON, breaks a field’s rules, or has a field this operation does not accept ("property <name> should not exist"). |
| 400 | [`bad_request`](https://hub.main-team.org/api/errors#bad_request) | `password` was sent. The check never takes one: leave it out, and send it with `registerStudent` only. |
| 400 | [`bad_request`](https://hub.main-team.org/api/errors#bad_request) | `lastName` is missing or empty. |
| 400 | [`bad_request`](https://hub.main-team.org/api/errors#bad_request) | `birth` is not `DD/MM/YYYY`, or is not a date that exists, such as `31/02/2008`. |
| 401 | [`unauthorized`](https://hub.main-team.org/api/errors#unauthorized) | The token is missing or malformed, is not signed with your account’s `apiSecret`, breaks the `iat` and `exp` rules, has expired or been revoked, or its account is not active. All of these answer the same. |
| 403 | [`forbidden`](https://hub.main-team.org/api/errors#forbidden) | The token is valid, but no role on your account allows `student/create` on `mto`, the organization every operation without `:organizationId` acts on, or a role denies it. |
| 413 | [`payload_too_large`](https://hub.main-team.org/api/errors#payload_too_large) | The body is larger than 100 kB. |
| 415 | [`unsupported_media_type`](https://hub.main-team.org/api/errors#unsupported_media_type) | The body declares a charset that is not a UTF one (send UTF-8), or a `Content-Encoding` other than gzip, deflate or br. |
| 429 | [`too_many_requests`](https://hub.main-team.org/api/errors#too_many_requests) | Your account has made more than 100 requests to this operation in the current 60-second window. Wait the seconds in `Retry-After` before sending again. |
| 500 | [`internal_error`](https://hub.main-team.org/api/errors#internal_error) | Something failed on our side. Retry later, and quote `request_id` if it goes on. |

## Code samples

### curl

```bash
# $TOKEN: a short-lived token you minted with your API key and secret
curl -sS -X POST 'https://api.main-team.org/v1/student/check' \
  -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  --data-binary @- <<'JSON'
{
  "firstName": "Jane",
  "lastName": "Doe",
  "birth": "14/05/2008",
  "sex": "f",
  "email": "jane.doe@example.com",
  "email2": "<email2>",
  "phone": "+1 555 0100",
  "country": "6650a1b2c3d4e5f6a7b8c9d1",
  "grade": "10",
  "school": "Springfield High School",
  "city": "Springfield",
  "activatedPlatformsThisSeason": [
    "common"
  ]
}
JSON
```

### Node.js

```js
const token = process.env.TOKEN; // a short-lived token you minted with your API key and secret

const res = await fetch('https://api.main-team.org/v1/student/check', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    "firstName": "Jane",
    "lastName": "Doe",
    "birth": "14/05/2008",
    "sex": "f",
    "email": "jane.doe@example.com",
    "email2": "<email2>",
    "phone": "+1 555 0100",
    "country": "6650a1b2c3d4e5f6a7b8c9d1",
    "grade": "10",
    "school": "Springfield High School",
    "city": "Springfield",
    "activatedPlatformsThisSeason": [
      "common"
    ]
  }),
});
const body = await res.json();
if (!res.ok) throw new Error(`${res.status} ${body.error.code}: ${body.error.message}`);
console.log(body.data);
```

### PHP

```php
<?php
$token = getenv('TOKEN'); // a short-lived token you minted with your API key and secret

$ch = curl_init('https://api.main-team.org/v1/student/check');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'firstName' => 'Jane',
        'lastName' => 'Doe',
        'birth' => '14/05/2008',
        'sex' => 'f',
        'email' => 'jane.doe@example.com',
        'email2' => '<email2>',
        'phone' => '+1 555 0100',
        'country' => '6650a1b2c3d4e5f6a7b8c9d1',
        'grade' => '10',
        'school' => 'Springfield High School',
        'city' => 'Springfield',
        'activatedPlatformsThisSeason' => [
            'common',
        ],
    ]),
    CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
if ($response === false) {
    throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
$body = json_decode($response, true);
if ($status >= 400) {
    $error = $body['error'];
    throw new RuntimeException("$status {$error['code']}: {$error['message']}");
}
print_r($body['data']);
```
