> ## 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.

# Beiträge und Medien

> Beiträge für eingebettete Kunden sofort veröffentlichen, planen und Medien hochladen

Beiträge gehören zu einem Endnutzer und müssen auf eine der Social-Verbindungen dieses Endnutzers zielen. Die Plattform der `connectionId` muss mit `socialMedia` übereinstimmen.

## Einen Textbeitrag erstellen

Lass `scheduledAt` weg, um den Beitrag sofort in die Warteschlange zu stellen:

```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" },
);
```

Zum Planen übergibst du einen ISO-8601-Zeitstempel:

```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]
>
> Verwende für jeden logischen Beitrag einen stabilen, eindeutigen Idempotenzschlüssel. Wenn deine Anfrage in ein Timeout läuft, wiederhole sie mit demselben Schlüssel. Schlüssel müssen 1 bis 255 Zeichen enthalten und gelten im Workspace des Endnutzers.

## Beiträge auflisten und abrufen

```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` ist auf 1 bis 100 beschränkt. Die Listenantwort enthält `data`, `page`, `limit` und `total`.

## Medien hochladen

Medien-Uploads folgen einem Ablauf in drei Schritten:

1. Fordere bei Social media studio eine vorsignierte Upload-URL an.
2. Lade die rohen Dateibytes per HTTP `PUT` direkt an diese URL hoch. Sende einen `Content-Type`-Header, der dem von dir angegebenen `mimetype` entspricht: Die URL ist damit signiert, daher schlägt ein `PUT` ohne diesen Header oder mit einem anderen Wert mit `403 SignatureDoesNotMatch` fehl.
3. Hänge die zurückgegebenen Dateiinformationen an, wenn du den Beitrag erstellst.

```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" },
);
```

Gib bei Videos beim Anfordern der URL und beim Anhängen der Datei zusätzlich `duration` in Sekunden an. Upload-URLs sind temporär; fordere eine neue an, wenn ein Upload abgelaufen ist.

## Beitragsstatus

Die Antwort auf das Erstellen bestätigt, dass der Beitrag angenommen und in die Warteschlange gestellt wurde; sie garantiert nicht, dass die Social-Plattform ihn veröffentlicht hat. Das endgültige Ergebnis erhältst du über `post.status`, durch Abfragen von `posts.get` oder indem du die Webhooks `post.published` und `post.failed` abonnierst.


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