# Démarrage rapide de l'API

## Démarrage rapide de l’API

Authentifiez-vous et effectuez vos premiers appels API.

### 1. Obtenir votre jeton

Générez un jeton Bearer dans le portail sous Profile → API Tokens. Chaque requête utilise l’URL de base `https://api.zcp.zsoftly.ca/api` et envoie le jeton dans l’en-tête `Authorization`.

### 2. Lister vos machines virtuelles

L’exemple ci-dessous s’authentifie et liste vos machines virtuelles. Choisissez votre langage et remplacez `your-token` par votre jeton API.

#### cURL

```bash
curl -s "https://api.zcp.zsoftly.ca/api/virtual-machines" \
  -H "Authorization: Bearer your-token" \
  -H "Accept: application/json" | jq '.data'
```

#### Python

```python
import requests


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token"  # Profile -> API Tokens


resp = requests.get(
    f"{BASE}/virtual-machines",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
for vm in resp.json()["data"]:
    print(vm["name"], vm["state"])
```

#### JavaScript

```js
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token'; // Profile -> API Tokens


const res = await fetch(`${BASE}/virtual-machines`, {
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
const { data } = await res.json();
for (const vm of data) {
  console.log(vm.name, vm.state);
}
```

#### TypeScript

```ts
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token'; // Profile -> API Tokens


interface VM {
  name: string;
  state: string;
}


const res = await fetch(`${BASE}/virtual-machines`, {
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
const { data } = (await res.json()) as { data: VM[] };
for (const vm of data) {
  console.log(vm.name, vm.state);
}
```

#### Go

```go
package main


import (
  "encoding/json"
  "fmt"
  "net/http"
)


func main() {
  const base = "https://api.zcp.zsoftly.ca/api"
  const token = "your-token" // Profile -> API Tokens


  req, _ := http.NewRequest("GET", base+"/virtual-machines", nil)
  req.Header.Set("Authorization", "Bearer "+token)
  req.Header.Set("Accept", "application/json")


  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()


  var env struct {
    Data []struct {
      Name  string `json:"name"`
      State string `json:"state"`
    } `json:"data"`
  }
  json.NewDecoder(resp.Body).Decode(&env)
  for _, vm := range env.Data {
    fmt.Println(vm.Name, vm.State)
  }
}
```

#### C#

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;


class Program
{
    static async Task Main()
    {
        const string baseUrl = "https://api.zcp.zsoftly.ca/api";
        const string token = "your-token"; // Profile -> API Tokens


        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", token);
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));


        var json = await client.GetStringAsync($"{baseUrl}/virtual-machines");
        Console.WriteLine(json);
    }
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;


public class ListVms {
    public static void main(String[] args) throws Exception {
        String base = "https://api.zcp.zsoftly.ca/api";
        String token = "your-token"; // Profile -> API Tokens


        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(base + "/virtual-machines"))
            .header("Authorization", "Bearer " + token)
            .header("Accept", "application/json")
            .GET()
            .build();


        HttpResponse<String> res = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(res.body());
    }
}
```

#### Ruby

```ruby
require "net/http"
require "json"
require "uri"


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token" # Profile -> API Tokens


uri = URI("#{BASE}/virtual-machines")
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Accept"] = "application/json"


res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
JSON.parse(res.body)["data"].each do |vm|
  puts "#{vm['name']} #{vm['state']}"
end
```

#### PHP

```php
<?php
$base = "https://api.zcp.zsoftly.ca/api";
$token = "your-token"; // Profile -> API Tokens


$ch = curl_init("$base/virtual-machines");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $token",
    "Accept: application/json",
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);


foreach ($body["data"] as $vm) {
    echo "{$vm['name']} {$vm['state']}\n";
}
```

### 3. Créer une machine virtuelle

Les slugs pour `project`, `region`, `template`, `plan` et `networks` proviennent des points de terminaison de liste correspondants (`/projects`, `/regions`, `/templates`, `/plans/service/compute`, `/networks`). Consultez la [référence de l’API Cloud Platform](https://api.zcp.zsoftly.ca/api/docs/nimbo) pour le schéma de requête complet.

#### cURL

```bash
curl -s -X POST "https://api.zcp.zsoftly.ca/api/virtual-machines" \
  -H "Authorization: Bearer your-token" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "name": "my-server",
    "project": "default",
    "region": "yow",
    "boot_source": "template",
    "template": "ubuntu-24-04",
    "plan": "ci1xs",
    "network_type": "public",
    "networks": ["my-public-network"],
    "is_public": true,
    "billing_cycle": "hourly",
    "hostname": "my-server"
  }' | jq '.data'
```

#### Python

```python
import requests


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token"


vm = {
    "name": "my-server",
    "project": "default",
    "region": "yow",
    "boot_source": "template",
    "template": "ubuntu-24-04",
    "plan": "ci1xs",
    "network_type": "public",
    "networks": ["my-public-network"],
    "is_public": True,
    "billing_cycle": "hourly",
    "hostname": "my-server",
}


resp = requests.post(
    f"{BASE}/virtual-machines",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
    json=vm,
)
print(resp.json()["data"])
```

#### JavaScript

```js
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token';


const res = await fetch(`${BASE}/virtual-machines`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({
    name: 'my-server',
    project: 'default',
    region: 'yow',
    boot_source: 'template',
    template: 'ubuntu-24-04',
    plan: 'ci1xs',
    network_type: 'public',
    networks: ['my-public-network'],
    is_public: true,
    billing_cycle: 'hourly',
    hostname: 'my-server',
  }),
});
console.log((await res.json()).data);
```

#### TypeScript

```ts
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token';


const res = await fetch(`${BASE}/virtual-machines`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    'Content-Type': 'application/json',
    Accept: 'application/json',
  },
  body: JSON.stringify({
    name: 'my-server',
    project: 'default',
    region: 'yow',
    boot_source: 'template',
    template: 'ubuntu-24-04',
    plan: 'ci1xs',
    network_type: 'public',
    networks: ['my-public-network'],
    is_public: true,
    billing_cycle: 'hourly',
    hostname: 'my-server',
  }),
});
console.log((await res.json()).data);
```

#### Go

```go
package main


import (
  "bytes"
  "encoding/json"
  "fmt"
  "net/http"
)


func main() {
  const base = "https://api.zcp.zsoftly.ca/api"
  const token = "your-token"


  body := []byte(`{
    "name": "my-server",
    "project": "default",
    "region": "yow",
    "boot_source": "template",
    "template": "ubuntu-24-04",
    "plan": "ci1xs",
    "network_type": "public",
    "networks": ["my-public-network"],
    "is_public": true,
    "billing_cycle": "hourly",
    "hostname": "my-server"
  }`)


  req, _ := http.NewRequest("POST", base+"/virtual-machines", bytes.NewReader(body))
  req.Header.Set("Authorization", "Bearer "+token)
  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("Accept", "application/json")


  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()


  var env struct {
    Data json.RawMessage `json:"data"`
  }
  json.NewDecoder(resp.Body).Decode(&env)
  fmt.Println(string(env.Data))
}
```

#### C#

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;


class Program
{
    static async Task Main()
    {
        const string baseUrl = "https://api.zcp.zsoftly.ca/api";
        const string token = "your-token";


        var body = """
        {
          "name": "my-server",
          "project": "default",
          "region": "yow",
          "boot_source": "template",
          "template": "ubuntu-24-04",
          "plan": "ci1xs",
          "network_type": "public",
          "networks": ["my-public-network"],
          "is_public": true,
          "billing_cycle": "hourly",
          "hostname": "my-server"
        }
        """;


        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", token);
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));


        var content = new StringContent(body, Encoding.UTF8, "application/json");
        var resp = await client.PostAsync($"{baseUrl}/virtual-machines", content);
        Console.WriteLine(await resp.Content.ReadAsStringAsync());
    }
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;


public class CreateVm {
    public static void main(String[] args) throws Exception {
        String base = "https://api.zcp.zsoftly.ca/api";
        String token = "your-token";


        String body = """
            {
              "name": "my-server",
              "project": "default",
              "region": "yow",
              "boot_source": "template",
              "template": "ubuntu-24-04",
              "plan": "ci1xs",
              "network_type": "public",
              "networks": ["my-public-network"],
              "is_public": true,
              "billing_cycle": "hourly",
              "hostname": "my-server"
            }
            """;


        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(base + "/virtual-machines"))
            .header("Authorization", "Bearer " + token)
            .header("Content-Type", "application/json")
            .header("Accept", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();


        HttpResponse<String> res = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(res.body());
    }
}
```

#### Ruby

```ruby
require "net/http"
require "json"
require "uri"


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token"


uri = URI("#{BASE}/virtual-machines")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Content-Type"] = "application/json"
req["Accept"] = "application/json"
req.body = {
  name: "my-server",
  project: "default",
  region: "yow",
  boot_source: "template",
  template: "ubuntu-24-04",
  plan: "ci1xs",
  network_type: "public",
  networks: ["my-public-network"],
  is_public: true,
  billing_cycle: "hourly",
  hostname: "my-server",
}.to_json


res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)["data"]
```

#### PHP

```php
<?php
$base = "https://api.zcp.zsoftly.ca/api";
$token = "your-token";


$vm = [
    "name" => "my-server",
    "project" => "default",
    "region" => "yow",
    "boot_source" => "template",
    "template" => "ubuntu-24-04",
    "plan" => "ci1xs",
    "network_type" => "public",
    "networks" => ["my-public-network"],
    "is_public" => true,
    "billing_cycle" => "hourly",
    "hostname" => "my-server",
];


$ch = curl_init("$base/virtual-machines");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($vm));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $token",
    "Content-Type: application/json",
    "Accept: application/json",
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);


print_r($body["data"]);
```

### 4. Gérer une machine virtuelle

Les actions du cycle de vie d’une VM utilisent le slug de la VM et le nom de l’action, soit `start`, `stop`, `reboot` ou `reset`.

#### cURL

```bash
curl -s -X PUT "https://api.zcp.zsoftly.ca/api/virtual-machines/my-server/stop" \
  -H "Authorization: Bearer your-token" \
  -H "Accept: application/json" | jq '.message'
```

#### Python

```python
import requests


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token"


resp = requests.put(
    f"{BASE}/virtual-machines/my-server/stop",
    headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
)
print(resp.json()["message"])
```

#### JavaScript

```js
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token';


const res = await fetch(`${BASE}/virtual-machines/my-server/stop`, {
  method: 'PUT',
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
console.log((await res.json()).message);
```

#### TypeScript

```ts
const BASE = 'https://api.zcp.zsoftly.ca/api';
const TOKEN = 'your-token';


const res = await fetch(`${BASE}/virtual-machines/my-server/stop`, {
  method: 'PUT',
  headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
console.log((await res.json()).message);
```

#### Go

```go
package main


import (
  "encoding/json"
  "fmt"
  "net/http"
)


func main() {
  const base = "https://api.zcp.zsoftly.ca/api"
  const token = "your-token"


  req, _ := http.NewRequest("PUT", base+"/virtual-machines/my-server/stop", nil)
  req.Header.Set("Authorization", "Bearer "+token)
  req.Header.Set("Accept", "application/json")


  resp, err := http.DefaultClient.Do(req)
  if err != nil {
    panic(err)
  }
  defer resp.Body.Close()


  var env struct {
    Message string `json:"message"`
  }
  json.NewDecoder(resp.Body).Decode(&env)
  fmt.Println(env.Message)
}
```

#### C#

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;


class Program
{
    static async Task Main()
    {
        const string baseUrl = "https://api.zcp.zsoftly.ca/api";
        const string token = "your-token";


        using var client = new HttpClient();
        client.DefaultRequestHeaders.Authorization =
            new AuthenticationHeaderValue("Bearer", token);
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));


        var resp = await client.PutAsync($"{baseUrl}/virtual-machines/my-server/stop", null);
        Console.WriteLine(await resp.Content.ReadAsStringAsync());
    }
}
```

#### Java

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;


public class ManageVm {
    public static void main(String[] args) throws Exception {
        String base = "https://api.zcp.zsoftly.ca/api";
        String token = "your-token";


        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(base + "/virtual-machines/my-server/stop"))
            .header("Authorization", "Bearer " + token)
            .header("Accept", "application/json")
            .PUT(HttpRequest.BodyPublishers.noBody())
            .build();


        HttpResponse<String> res = HttpClient.newHttpClient()
            .send(req, HttpResponse.BodyHandlers.ofString());
        System.out.println(res.body());
    }
}
```

#### Ruby

```ruby
require "net/http"
require "json"
require "uri"


BASE = "https://api.zcp.zsoftly.ca/api"
TOKEN = "your-token"


uri = URI("#{BASE}/virtual-machines/my-server/stop")
req = Net::HTTP::Put.new(uri)
req["Authorization"] = "Bearer #{TOKEN}"
req["Accept"] = "application/json"


res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)["message"]
```

#### PHP

```php
<?php
$base = "https://api.zcp.zsoftly.ca/api";
$token = "your-token";


$ch = curl_init("$base/virtual-machines/my-server/stop");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    "Authorization: Bearer $token",
    "Accept: application/json",
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);


echo $body["message"] . "\n";
```

### Infrastructure comme code (IaC)

Le fournisseur officiel Terraform / OpenTofu gère les machines virtuelles, les réseaux, Kubernetes, le DNS, le stockage et plus encore, de manière déclarative. Vous le trouvez sous `zsoftly/zcp` dans le [registre Terraform](https://registry.terraform.io/providers/zsoftly/zcp) et le [registre OpenTofu](https://search.opentofu.org/provider/zsoftly/zcp). Commencez par le [tutoriel Terraform / OpenTofu](https://docs.zcp.zsoftly.ca/tutorials/manage-infrastructure-terraform/) (en anglais).

### Gestion de la configuration

Une collection Ansible sera bientôt disponible. Elle permettra de provisionner et de configurer les ressources ZSoftly depuis vos playbooks. Des modules et exemples de playbooks seront publiés ici.

### Référence API complète

La référence API interactive complète est disponible dans Swagger UI :

- API Cloud Platform : [Ouvrir Swagger UI](https://api.zcp.zsoftly.ca/api/docs/nimbo)
- API Stockage objet : [Ouvrir Swagger UI](https://api.zcp.zsoftly.ca/api/docs/ceph)

Voir aussi : [Authentification](https://docs.zcp.zsoftly.ca/fr/public-cloud/api/authentication), [Référence API](https://docs.zcp.zsoftly.ca/fr/public-cloud/api/reference)
