# Is Valid Connection String API

> Test a database connection string before saving it with the is valid connection string system API of API Maker - MongoDB, MySQL, MariaDB, SQL Server, PostgreSQL and Oracle - the check behind the Test Instance button.

Source: https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-is-valid-connection-string-api.html

Opens a connection with the string given and closes it : the check the **Test Instance** button of the instances page makes. Useful for an onboarding screen which lets a customer register their own database, or before writing a tenant row.

| | |
|---|---|
| Method | POST |
| URL | `/api/system-api/admin/is-valid-connection-string` : `admin` is the user path of your account |
| Body | `{ connectionString, instanceType, oracleDBUsername?, oracleDBPassword?, oracleDBPrivilege? }` or an array of them |
| Answer | `data` : `{ success, data: true | false, error? }`, or an array of them |
| From code | [`g.sys.system.isValidConnectionString`](https://docs.apimaker.dev/v4/docs/apis-all/system-apis/system-generated-is-valid-connection-string-api.html#from-code) |

## The call

**Body**

```json
{ "connectionString": "postgresql://crm:secret@db-1:5432/crm_acme", "instanceType": "POSTGRE_SQL_DB" }
```

**Answer**

```json
{ "success": true, "statusCode": 200, "data": { "success": true, "data": true } }
```

**Answer when the database refuses**

```json
{ "success": true, "statusCode": 200, "data": { "success": false, "data": false, "error": "password authentication failed for user \"crm\"" } }
```

| Key | Meaning |
|---|---|
| `connectionString` | The string, in the format of the database : see the [connection strings](https://docs.apimaker.dev/v4/docs/Database-connection-string/mongodb-connection-strings.html) pages. |
| `instanceType` | `MONGO_DB`, `MYSQL_DB`, `MARIA_DB`, `SQL_SERVER_DB`, `POSTGRE_SQL_DB` or `ORACLE_DB`. |
| `oracleDBUsername`, `oracleDBPassword`, `oracleDBPrivilege` | Oracle : the user, the password and the privilege, as on the instance form. |

- An array of bodies checks several strings in one call and answers an array in the same order.

## From code

**TypeScript**

```typescript
const cs = g.req.body.connectionString;
const check = await g.sys.system.isValidConnectionString({ connectionString: cs, instanceType: T.EInstanceType.POSTGRE_SQL_DB });
if (!check.success) throw new Error('This database can not be reached : ' + check.error);
```

**Python**

```python
cs = g.req.body.connectionString
check = await g.sys.system.is_valid_connection_string(cs, 'POSTGRE_SQL_DB')
if not check.success:
    raise Exception(f'This database can not be reached : {check.error}')
```

**PHP**

```php
$cs = $g->req->body->connectionString;
$check = $g->sys->system->isValidConnectionString($cs, 'POSTGRE_SQL_DB');
if (!$check->success) {
    throw new Exception('This database can not be reached : ' . json_encode($check->error));
}
```

**C#**

```csharp
var cs = g.Req.Body.GetString("connectionString");
var check = await g.Sys.System.IsValidConnectionString(new IsValidConnectionString(cs, "POSTGRE_SQL_DB"));
if (!check.Success) throw new Exception($"This database can not be reached : {check.Error}");
```

**Go**

```go
import "fmt"

cs := g.Req.Body().String("connectionString")
check, err := g.Sys.System.IsValidConnectionString(am.IsValidConnectionString{ConnectionString: cs, InstanceType: "POSTGRE_SQL_DB"})
if err != nil {
	return nil, err
}
if !check.Success {
	return nil, fmt.Errorf("This database can not be reached : %v", check.Error)
}
```

**Rust**

```rust
let cs = g.req.body()["connectionString"].as_str().unwrap_or_default().to_owned();
let check = g.sys.system.is_valid_connection_string(IsValidConnectionString::new(cs, "POSTGRE_SQL_DB"))?;
if !check.success {
    return Err(am::fail(500, &format!("This database can not be reached : {}", check.error)));
}
```

**Java**

```java
String cs = g.req.getBody().getString("connectionString");
Checked check = g.sys.system.isValidConnectionString(new IsValidConnectionString(cs, "POSTGRE_SQL_DB"));
if (!check.isSuccess()) throw new IllegalStateException("This database can not be reached : " + check.getError());
```

**Kotlin**

```kotlin
val cs = g.req.body.getString("connectionString")
val check = g.sys.system.isValidConnectionString(IsValidConnectionString(cs, "POSTGRE_SQL_DB"))
if (!check.isSuccess) throw IllegalStateException("This database can not be reached : ${check.error}")
```

## Access and settings

- Over HTTP, a system API answers once its [settings](https://docs.apimaker.dev/v4/docs/settings/systemApiSettings.html) give it `apiAccessType: TOKEN_ACCESS` (the token of an API user whose [group](https://docs.apimaker.dev/v4/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/v4/docs/apis-all/hooks/preHook-api.html) run around it like around any API.
- The [request headers](https://docs.apimaker.dev/v4/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. |
| `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/v4/docs/apis-all/overview.html) · [Response format](https://docs.apimaker.dev/v4/docs/apis-all/response-format.html) · [System API settings](https://docs.apimaker.dev/v4/docs/settings/systemApiSettings.html) · [System APIs from code](https://docs.apimaker.dev/v4/examples/sys/system/system.html)
