# Is Valid Data for Custom API

> Check a body or query params against the request schema of a custom API without calling it, with the is valid data for custom API system API of API Maker.

Source: https://docs.apimaker.dev/v1/docs/apis-all/system-apis/system-generated-is-valid-data-for-custom-api.html

Runs the `reqBodySchema` or `reqQueryParametersSchema` of a [custom API](https://docs.apimaker.dev/v1/docs/apis-all/custom-apis/user-created-custom-api.html) on some data and answers the errors the API would refuse it with, without running the API.

| | |
|---|---|
| Method | POST |
| URL | `/api/system-api/admin/is-valid-data-for-custom-api` : `admin` is the user path of your account |
| Body | `{ name, type, data }` or an array of them |
| Answer | `data` : an array of errors (empty when valid), or an array of arrays |
| From code | [`g.sys.system.isValidDataForCustomAPI`](https://docs.apimaker.dev/v1/examples/sys/system/isValidDataForCustomAPI.html) |

## The custom API settings

**Basic info of the custom API**

```typescript
let customApi: T.ICustomApiSettingsTypes = {
    name: 'Create Customer', path: '/customers', requestMethod: T.ERequestMethod.POST, errorList: [],
    reqBodySchema: {
        first_name: { __type: T.EType.string, validations: { required: true } },
        phone: { __type: T.EType.number, validations: { required: true, min: 5, max: 999 } },
    },
};
```

## The call

**Body**

```json
{ "name": "Create Customer", "type": "BODY", "data": { "phone": 3 } }
```

**Answer**

```json
{
    "success": true,
    "statusCode": 200,
    "data": [
        { "type": "required", "field": "first_name", "message": "Please provide valid 'first_name' field with type 'string'.", "code": 400 },
        { "type": "min", "field": "phone", "message": "Please provide minimum '5' for 'phone' field.", "code": 400 }
    ]
}
```

| Key | Meaning |
|---|---|
| `name` | The name of the custom API. |
| `type` | `BODY` for `reqBodySchema`, `QUERY_PARAMS` for `reqQueryParametersSchema`. |
| `data` | The body or the query params to check. |

## From code

```typescript
const errors = await g.sys.system.isValidDataForCustomAPI({ name: 'Create Customer', type: T.ECustomAPIDataValidationType.BODY, data: draft });
```

## Access and settings

- Over HTTP, a system API answers once its [settings](https://docs.apimaker.dev/v1/docs/settings/systemApiSettings.html) give it `apiAccessType: TOKEN_ACCESS` (the token of an API user whose [group](https://docs.apimaker.dev/v1/docs/apis-security/api-group-permission.html) grants this system API, in `x-am-authorization`) or `IS_PUBLIC`. Without settings it is `NO_ACCESS` : your code calls it through `g.sys`, the admin panel tests it, and an HTTP call is refused.
- The settings can also cache the answer or require person tokens (`authProviders`) ; [pre and post hooks](https://docs.apimaker.dev/v1/docs/apis-all/hooks/preHook-api.html) run around it like around any API.
- The [request headers](https://docs.apimaker.dev/v1/docs/apis-all/header/requestHeader.html) apply : `x-am-response-case`, `x-am-content-type-response`, `x-am-internationalization`, `x-am-tenant-username`…

## Errors

| Code | When |
|---|---|
| `400` | The body is wrong : the message names the missing or invalid key, `Unable to find custom API with name …`. |
| `401` | No valid API user token, or the API is `NO_ACCESS` : `You are not authorized to access this API.` |
| `403` | No group grants this system API. |

## Related

- [All APIs at a glance](https://docs.apimaker.dev/v1/docs/apis-all/overview.html) · [Response format](https://docs.apimaker.dev/v1/docs/apis-all/response-format.html) · [System API settings](https://docs.apimaker.dev/v1/docs/settings/systemApiSettings.html) · [System APIs from code](https://docs.apimaker.dev/v1/examples/sys/system/system.html)
