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

# Publications et médias

> Publiez immédiatement, programmez des publications et importez des médias pour vos clients intégrés

Les publications appartiennent à un utilisateur final et doivent cibler l'une de ses connexions
sociales. La plateforme de `connectionId` doit correspondre à `socialMedia`.

## Créer une publication texte

Omettez `scheduledAt` pour mettre la publication en file d'attente immédiatement :

```ts theme={null}
const post = await soMe.posts.create(
  endUser.id,
  {
    connectionId: connection.id,
    socialMedia: "THREADS",
    postType: "TEXT",
    text: "Published through our app",
  },
  { idempotencyKey: "customer_123:post_456" },
);
```

Pour la programmer, transmettez un horodatage ISO 8601 :

```ts theme={null}
const post = await soMe.posts.create(
  endUser.id,
  {
    connectionId: connection.id,
    socialMedia: "THREADS",
    postType: "TEXT",
    text: "See you tomorrow",
    scheduledAt: "2026-08-20T10:00:00Z",
  },
  { idempotencyKey: "customer_123:post_457" },
);
```

> [!WARNING]
>
> Utilisez une clé d'idempotence stable et unique pour chaque publication logique. Si votre requête
> expire, relancez-la avec la même clé. Les clés doivent contenir de 1 à 255 caractères et sont
> limitées à l'espace de travail de l'utilisateur final.

## Lister et récupérer des publications

```ts theme={null}
const page = await soMe.posts.list(endUser.id, {
  page: 1,
  limit: 20,
});

const post = await soMe.posts.get(endUser.id, "post_uuid");
```

`limit` est limité à une valeur comprise entre 1 et 100. La réponse de la liste contient `data`, `page`,
`limit` et `total`.

## Importer des médias

L'import de médias se fait en trois étapes :

1. Demandez à Social media studio une URL d'import pré-signée.
2. Envoyez les octets bruts du fichier directement à cette URL avec un `PUT` HTTP. Envoyez un
   en-tête `Content-Type` identique au `mimetype` que vous avez déclaré : l'URL est
   signée avec cette valeur, donc un `PUT` sans cet en-tête, ou avec une autre valeur, échoue avec
   `403 SignatureDoesNotMatch`.
3. Joignez les informations de fichier renvoyées lors de la création de la publication.

```ts theme={null}
import { readFile, stat } from "node:fs/promises";

const filename = "launch.jpg";
const mimetype = "image/jpeg";
const size = (await stat(filename)).size;

const [media] = await soMe.posts.presignMedia(endUser.id, {
  postType: "IMAGE",
  socialMedia: "THREADS",
  files: [{ filename, mimetype, size }],
});

const upload = await fetch(media.uploadUrl, {
  method: "PUT",
  headers: { "Content-Type": mimetype },
  body: await readFile(filename),
});

if (!upload.ok) {
  throw new Error(`Media upload failed: ${upload.status}`);
}

const post = await soMe.posts.create(
  endUser.id,
  {
    connectionId: connection.id,
    socialMedia: "THREADS",
    postType: "IMAGE",
    text: "Our launch is live",
    files: [
      {
        id: media.fileId,
        filename,
        mimetype,
        size,
        s3Prefix: media.s3Prefix,
        fileSrc: media.fileSrc,
      },
    ],
  },
  { idempotencyKey: "customer_123:post_458" },
);
```

Pour les vidéos, indiquez `duration` en secondes lors de la demande d'URL et de la jonction
du fichier. Les URL d'import sont temporaires ; demandez-en une nouvelle si un import a expiré.

## Statut de la publication

La réponse de création confirme que la publication a été acceptée et mise en file d'attente ; elle ne
garantit pas que la plateforme sociale l'a publiée. Utilisez `post.status`, interrogez
`posts.get` ou abonnez-vous aux webhooks `post.published` et `post.failed` pour obtenir le
résultat final.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.