> ## Documentation Index
> Fetch the complete documentation index at: https://docs.squarecloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Compatibilité S3

> Utilisez aws-cli, boto3, rclone et les SDK AWS avec Blob Storage via la passerelle compatible S3 : endpoint, buckets, opérations prises en charge et limites.

Blob Storage parle l'API S3 à l'adresse `https://s3-blob.squarecloud.app`. Tout outil qui permet de définir un endpoint personnalisé fonctionne : aws-cli, boto3, le SDK AWS pour JavaScript, rclone, Cyberduck et la plupart des outils de sauvegarde.

## Identifiants

Les outils S3 signent les requêtes avec une paire de clés d'accès. Obtenez-la via [Identifiants S3](/fr/blob-reference/endpoint/s3-credentials) :

```bash theme={null}
curl https://blob.squarecloud.app/v1/s3/credentials \
  --header 'Authorization: YOUR_API_KEY'
```

La paire est **dérivée de votre clé API**. Elle ne nécessite aucune gestion séparée : révoquer ou régénérer la clé fait de même pour la paire, et la paire reçoit les mêmes scopes. Une clé avec uniquement `blob:read` donne une paire en lecture seule.

La paire ne change pas tant que la clé API ne change pas : récupérez-la donc une fois et conservez-la dans votre gestionnaire de secrets ou dans une variable d'environnement. N'appelez pas la route à chaque démarrage : elle accepte 10 requêtes par heure.

| Paramètre | Valeur                                                        |
| --------- | ------------------------------------------------------------- |
| Endpoint  | `https://s3-blob.squarecloud.app`                             |
| Région    | `auto`                                                        |
| Adressage | Path-style (`https://s3-blob.squarecloud.app/<bucket>/<key>`) |
| Signature | AWS Signature Version 4                                       |

## Buckets

Votre compte voit trois buckets fixes. Vous ne pouvez pas créer ni supprimer de buckets.

| Bucket    | Contenu                                                                         | Accès                           |
| --------- | ------------------------------------------------------------------------------- | ------------------------------- |
| `public`  | Fichiers publics, servis sur `https://blob.squarecloud.dev/pub/<user_id>/<key>` | Lecture et écriture             |
| `private` | Fichiers privés, sans URL publique                                              | Lecture et écriture             |
| `legacy`  | Fichiers hérités, envoyés avant la mise à jour de septembre 2026                | Lecture, listage et suppression |

Une clé dans le bucket `public` ou `private` est le chemin de l'objet **sans** votre id utilisateur : `images/logo.png` dans le bucket `public` correspond à l'objet `pub/<user_id>/images/logo.png` sur l'API REST. Les fichiers écrits via S3 apparaissent sur l'API REST et dans le tableau de bord, et inversement.

## Configuration

<CodeGroup>
  ```bash aws-cli theme={null}
  aws configure set aws_access_key_id SQ2_...
  aws configure set aws_secret_access_key ...
  aws configure set region auto

  aws s3 cp ./logo.png s3://public/images/logo.png \
    --endpoint-url https://s3-blob.squarecloud.app
  aws s3 ls s3://public/images/ --endpoint-url https://s3-blob.squarecloud.app
  ```

  ```python boto3 theme={null}
  import boto3
  from botocore.config import Config

  s3 = boto3.client(
      "s3",
      endpoint_url="https://s3-blob.squarecloud.app",
      aws_access_key_id="SQ2_...",
      aws_secret_access_key="...",
      region_name="auto",
      config=Config(signature_version="s3v4", s3={"addressing_style": "path"}),
  )

  s3.upload_file("report.pdf", "private", "reports/2026/report.pdf")
  url = s3.generate_presigned_url(
      "get_object",
      Params={"Bucket": "private", "Key": "reports/2026/report.pdf"},
      ExpiresIn=3600,
  )
  ```

  ```javascript AWS SDK v3 theme={null}
  import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";

  const s3 = new S3Client({
    endpoint: "https://s3-blob.squarecloud.app",
    region: "auto",
    forcePathStyle: true,
    credentials: { accessKeyId: "SQ2_...", secretAccessKey: "..." },
  });

  await s3.send(new PutObjectCommand({
    Bucket: "public",
    Key: "images/logo.png",
    Body: buffer,
    ContentType: "image/png",
  }));
  ```

  ```ini rclone theme={null}
  [squarecloud]
  type = s3
  provider = Other
  access_key_id = SQ2_...
  secret_access_key = ...
  endpoint = https://s3-blob.squarecloud.app
  region = auto
  force_path_style = true
  ```
</CodeGroup>

<Note>boto3 a besoin de `signature_version="s3v4"` pour les URL présignées : sans cela, `generate_presigned_url` signe avec l'ancien SigV2, que la passerelle n'accepte pas. Les URL présignées durent jusqu'à 7 jours (604800 secondes).</Note>

Les réponses de la passerelle ne sont jamais mises en cache en périphérie. Une URL présignée cesse de fonctionner exactement à son expiration, lorsque la clé API est révoquée ou lorsque l'objet est supprimé.

## Opérations prises en charge

| Domaine       | Opérations                                                                                                                                                                                                                                                                                                  |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Buckets       | `ListBuckets`, `HeadBucket`, `GetBucketLocation`. `CreateBucket` sur un bucket existant réussit ; `DeleteBucket` répond `BucketNotEmpty` tant que le bucket contient des fichiers.                                                                                                                          |
| Listage       | `ListObjects` et `ListObjectsV2`, avec `delimiter`, `prefix` et `encoding-type=url`.                                                                                                                                                                                                                        |
| Objets        | `HeadObject`, `GetObject` (avec `Range`, `If-Match`, `If-None-Match`, `If-Modified-Since`), `PutObject` (jusqu'à 100 Mo en une seule requête), `CopyObject` (directives de métadonnées `COPY` et `REPLACE`), `DeleteObject`, `DeleteObjects` (jusqu'à 1000 clés).                                           |
| Multipart     | `CreateMultipartUpload`, `UploadPart` (de 5 Mo à 80 Mo par partie, sauf la dernière), `UploadPartCopy`, `CompleteMultipartUpload`, `AbortMultipartUpload`, `ListParts`, `ListMultipartUploads`. Objets jusqu'à 10 GiB.                                                                                      |
| Intégrité     | `Content-MD5` est toujours vérifié, même lorsqu'un en-tête `x-amz-checksum-*` est aussi envoyé. `x-amz-checksum-crc32`, `-sha1` et `-sha256` sont vérifiés aussi ; une différence répond `BadDigest`. `crc32c` et `crc64nvme` sont acceptés sans vérification. Les corps `aws-chunked` sont pris en charge. |
| Compatibilité | `GetBucketVersioning`, `GetBucketAcl`, `GetObjectAcl` et les lectures de tags renvoient des valeurs fixes afin que les outils qui les interrogent continuent de fonctionner.                                                                                                                                |

Les politiques de bucket, CORS, lifecycle, website, le chiffrement, object lock, les versions, la journalisation, les notifications, la réplication, les écritures d'ACL et de tags, le `GET` par `partNumber` et les envois par formulaire POST depuis le navigateur répondent `501 NotImplemented`. Utilisez les [paramètres du compte](/fr/blob-reference/endpoint/settings-put) pour les règles de cycle de vie.

## Clés

* Les clés sont des chemins littéraux. Une clé peut faire jusqu'à environ 1000 octets : la limite de 1024 octets compte aussi le préfixe du compte. Une clé plus longue répond `KeyTooLongError`, et son message indique le nombre exact d'octets dont vous disposez. Les segments ne peuvent pas être vides, `.` ou `..`.
* Une clé de 0 octet se terminant par `/` est un marqueur de dossier, à la manière dont la console AWS crée les dossiers.
* Le `Content-Type` servi est dérivé de l'extension, comme sur l'API REST. Les exécutables sont refusés avec `InvalidArgument` et `.html`, `.svg` et `.xml` sont servis en tant que téléchargements.

## Métadonnées, cache et expiration

* Les en-têtes `x-amz-meta-*` sont conservés sur **Pro et Enterprise** (jusqu'à 5 clés et 512 octets, sinon `MetadataTooLarge`). Sur les autres plans, ils sont ignorés.
* `Cache-Control` et `Content-Disposition` sont conservés. Un `Cache-Control` sans cache (`no-cache`, `no-store` ou `max-age=0`) en dehors d'Enterprise est refusé avec `AccessDenied`.
* Les [règles par préfixe](/fr/blob-reference/endpoint/settings-put) s'appliquent aux objets écrits via S3, y compris la suppression automatique. Les champs `max_size` et `extensions` d'une règle ne s'appliquent qu'aux envois REST.

## Limites

| Limite                                               | Valeur                                                              |
| ---------------------------------------------------- | ------------------------------------------------------------------- |
| Requêtes par compte, toutes les 10 secondes          | **Hobby** 100 · **Standard** 200 · **Pro** 400 · **Enterprise** 600 |
| Copies côté serveur (`CopyObject`, `UploadPartCopy`) | 20 par 10 secondes                                                  |
| Clés supprimées par `DeleteObjects`                  | 2000 par 10 secondes                                                |
| Envois multipart ouverts                             | 32 par compte, partagés avec les envois chunked REST                |
| `PutObject` unique                                   | 100 Mo                                                              |
| Partie (`UploadPart`)                                | 5 Mo à 80 Mo, sauf la dernière partie                               |
| Taille d'objet                                       | 10 GiB                                                              |
| Identifiants invalides                               | Trop d'échecs bloquent l'IP pendant quelques minutes                |

Au-delà d'une limite, la passerelle répond `SlowDown` (HTTP 503), et les SDK AWS patientent puis réessaient d'eux-mêmes. Les requêtes S3 **ne comptent pas** dans la limite de requêtes API de votre plan.

Vérifiez la paire de clés avant de réessayer en boucle : une IP qui envoie trop d'identifiants invalides est bloquée pendant quelques minutes.

### Taille des parties

Les outils multipart découpent eux-mêmes les gros fichiers ; gardez chaque partie à **80 Mo ou moins**. Les valeurs par défaut de l'AWS CLI (8 Mo) et de rclone (5 Mo) conviennent déjà.

<CodeGroup>
  ```bash aws-cli theme={null}
  aws configure set default.s3.multipart_chunksize 64MB
  ```

  ```python boto3 theme={null}
  from boto3.s3.transfer import TransferConfig

  config = TransferConfig(multipart_chunksize=64 * 1024 * 1024)
  s3.upload_file("backup.tar.gz", "private", "backups/backup.tar.gz", Config=config)
  ```

  ```javascript AWS SDK v3 theme={null}
  import { Upload } from "@aws-sdk/lib-storage";

  await new Upload({
    client: s3,
    params: { Bucket: "private", Key: "backups/backup.tar.gz", Body: stream },
    partSize: 64 * 1024 * 1024, // jusqu'à 80 Mo
  }).done();
  ```
</CodeGroup>

L'écriture nécessite un plan payant. Sans plan, et sur le bucket `legacy` en lecture seule, les écritures répondent `AccessDenied`. Le quota de stockage s'applique comme sur l'API REST.

## Erreurs

La passerelle répond avec les erreurs XML S3 standard, afin que les SDK les gèrent nativement :

| Erreur                                              | Quand                                                                                                                        |
| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `AccessDenied`                                      | Pas de plan payant, clé en lecture seule, écriture dans `legacy`, ou option en dehors de votre plan.                         |
| `NoSuchBucket`                                      | Le bucket n'est ni `public`, ni `private`, ni `legacy`.                                                                      |
| `NoSuchKey`                                         | L'objet n'existe pas.                                                                                                        |
| `InvalidArgument`                                   | Un type de fichier bloqué (exécutables et installateurs) ou un en-tête mal formé.                                            |
| `QuotaExceeded`                                     | Le compte a atteint son stockage inclus.                                                                                     |
| `EntityTooLarge` / `EntityTooSmall`                 | Un `PutObject` de plus de 100 Mo, une partie de plus de 80 Mo, ou une partie de moins de 5 Mo qui n'est pas la dernière.     |
| `InvalidPart` / `InvalidPartOrder` / `NoSuchUpload` | Finalisation multipart avec des parties incorrectes, ou un envoi qui n'existe plus.                                          |
| `BadDigest`                                         | Le corps ne correspond pas à `Content-MD5` ou à l'en-tête `x-amz-checksum-*`.                                                |
| `PreconditionFailed`                                | Une condition `If-Match` ou `If-None-Match` a échoué.                                                                        |
| `MetadataTooLarge`                                  | Plus de 5 clés de métadonnées ou de 512 octets.                                                                              |
| `KeyTooLongError`                                   | La clé est trop longue (environ 1000 octets). Le message indique la limite exacte pour votre compte.                         |
| `SlowDown`                                          | HTTP 503 : une limite de débit ou la limite d'envois ouverts a été atteinte. Les SDK réessaient d'eux-mêmes avec un backoff. |
| `NotImplemented`                                    | L'opération n'est pas prise en charge (voir ci-dessus).                                                                      |
