# MemeFlow Developer SDK & AI Agent Integration Guide (developer-sdk.md)

> **Production SDK Specification (`developer-sdk.md`)**  
> **API Version:** `v1` | **SDK Version:** `1.4.0`  
> **Application:** **MemeFlow Developer Starter** (`app_starter`)  
> **Base URL:** `https://creator-connect-earn.lovable.app`  
> **Generated:** `2026-10-05T23:28:57.759Z`

---

## 🤖 AI Coding Agent System Prompt (Copy & Paste)

Copy this entire block into **Cursor** (`.cursorrules`), **Claude Projects**, **Windsurf**, or **ChatGPT / Copilot**:

```markdown
You are an expert full-stack engineer integrating MemeFlow Connect into our application.
Use the following verified configuration:

- API Base URL: https://creator-connect-earn.lovable.app
- Application ID: app_starter
- Application Name: MemeFlow Developer Starter
- Auth Header: Authorization: Bearer <MEMEFLOW_API_KEY> (or X-API-Key: <MEMEFLOW_API_KEY>)
- Idempotency Header: Idempotency-Key: <UUID-v4> on mutative POST requests (/api/v1/posts, /api/v1/links, /api/v1/posts/temporary, /api/v1/partner/action, /api/v1/partner/content, /api/v1/partner/content/resolve)
- Multi-Track Audio: Preserve pristine BandLab-grade multi-track audio at 48kHz / 320kbps WAV/MP3 without downsampling.
- Browser-Local Partner Delivery: Use /api/v1/partner/content/resolve and /api/v1/partner/content (or /api/v1/posts/temporary) with HTTPS media_url / media[] descriptors for session-scoped browser-local delivery (delivery_mode: "browser_local").
- Permanent Posts & Smart Links: Use /api/v1/posts (with media_url / media[]) and /api/v1/links (with slug).
- Webhooks: Verify X-MemeFlow-Signature header formatted as t=<timestamp>,v1=<signature> using HMAC-SHA256 over "${timestamp}.${rawBody}".
- Rate Limits: 120 req/min (30 uploads/min). Implement exponential backoff on HTTP 429.
```

---

## 🔑 Environment Variables Setup

Add to your `.env` or deployment secrets:

```bash
# MemeFlow Connect Credentials
MEMEFLOW_API_KEY="YOUR_MEMEFLOW_API_KEY"
MEMEFLOW_APPLICATION_ID="app_starter"
MEMEFLOW_API_BASE_URL="https://creator-connect-earn.lovable.app"
MEMEFLOW_WEBHOOK_SECRET="whsec_YOUR_WEBHOOK_SECRET"
```

---

## 📦 Zero-Dependency TypeScript / Node.js Client

Save as `src/lib/memeflow-client.ts`:

```typescript
/**
 * MemeFlow Connect API Client (Zero external dependencies)
 * Application: MemeFlow Developer Starter (app_starter)
 */

export interface MediaDescriptor {
  media_url: string;
  media_type?: "image" | "video" | "audio" | "document" | "archive" | "other";
  file_name?: string;
  file_size?: number;
  audio_metadata?: {
    isMultiTrack?: boolean;
    sampleRate?: number;
    bitDepth?: number;
    channelCount?: number;
    tempoBpm?: number;
  };
}

export interface CreatePostParams {
  title: string;
  caption?: string;
  category?: string;
  externalReferenceId?: string;
  smartLinkSlug?: string;
  tags?: string[];
  mediaUrl?: string;
  media?: MediaDescriptor[];
}

export interface PartnerContentParams {
  partnerContentId: string;
  contentVersion?: string;
  action?: "view" | "download" | "watch" | "listen" | "save" | "open" | "export" | "share";
  title?: string;
  caption?: string;
  category?: string;
  mediaUrl?: string;
  media?: MediaDescriptor[];
  returnUrl?: string;
}

export class MemeFlowClient {
  private apiKey: string;
  private baseUrl: string;

  constructor(config?: { apiKey?: string; baseUrl?: string }) {
    this.apiKey = config?.apiKey || process.env.MEMEFLOW_API_KEY || "";
    this.baseUrl = (
      config?.baseUrl ||
      process.env.MEMEFLOW_API_BASE_URL ||
      "https://creator-connect-earn.lovable.app"
    ).replace(/\/+$/, "");

    if (!this.apiKey) {
      console.warn("[MemeFlowClient] Warning: MEMEFLOW_API_KEY is not defined.");
    }
  }

  private async request<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
    const url = `${this.baseUrl}${endpoint}`;
    const headers = new Headers(options.headers || {});

    headers.set("Authorization", `Bearer ${this.apiKey}`);
    headers.set("X-API-Key", this.apiKey);
    headers.set("Accept", "application/json");

    if (options.body && typeof options.body === "string" && !headers.has("Content-Type")) {
      headers.set("Content-Type", "application/json");
    }

    if (options.method === "POST" && !headers.has("Idempotency-Key")) {
      headers.set("Idempotency-Key", crypto.randomUUID());
    }

    const response = await fetch(url, { ...options, headers });

    if (!response.ok) {
      let errorBody: any;
      try {
        errorBody = await response.json();
      } catch {
        errorBody = { message: await response.text() };
      }
      throw new Error(
        `[MemeFlow API Error ${response.status}] ${errorBody?.error?.message || errorBody?.message || "Request failed"}`,
      );
    }

    return response.json();
  }

  /**
   * 1. Create a permanent post with HTTPS media_url or media[] descriptors (HTTP 201)
   */
  async createPost(params: CreatePostParams) {
    return this.request<{
      success: boolean;
      data: {
        post: { id: string; status: string };
        smart_link: string;
        smart_link_slug: string;
      };
    }>("/api/v1/posts", {
      method: "POST",
      body: JSON.stringify({
        title: params.title,
        caption: params.caption,
        category: params.category || "General",
        external_reference_id: params.externalReferenceId,
        smart_link_slug: params.smartLinkSlug,
        tags: params.tags || [],
        media_url: params.mediaUrl,
        media: params.media || [],
      }),
    });
  }

  /**
   * 2. Resolve or create a browser-local partner content delivery session
   */
  async resolvePartnerContent(partnerContentId: string, contentVersion = "1.0", action = "view") {
    return this.request<{
      status: "active" | "requires_upload";
      requires_upload?: boolean;
      post_id: string | null;
      smart_link: string | null;
      expires_at: string | null;
      delivery_mode: "browser_local";
    }>("/api/v1/partner/content/resolve", {
      method: "POST",
      body: JSON.stringify({
        partner_content_id: partnerContentId,
        content_version: contentVersion,
        action,
      }),
    });
  }

  async createPartnerContentSession(params: PartnerContentParams) {
    return this.request<{
      status: "active";
      post_id: string;
      smart_link: string;
      expires_at: string;
      delivery_mode: "browser_local";
    }>("/api/v1/partner/content", {
      method: "POST",
      body: JSON.stringify({
        partner_content_id: params.partnerContentId,
        content_version: params.contentVersion || "1.0",
        action: params.action || "view",
        title: params.title,
        caption: params.caption,
        category: params.category,
        return_url: params.returnUrl,
        media_url: params.mediaUrl,
        media: params.media,
      }),
    });
  }

  /**
   * 3. Generate a Smart Link for an existing post (HTTP 201)
   */
  async createSmartLink(postId: string, slug?: string) {
    return this.request<{
      success: boolean;
      data: {
        id: string;
        post_id: string;
        slug: string;
        smart_link_url: string;
      };
    }>("/api/v1/links", {
      method: "POST",
      body: JSON.stringify({
        post_id: postId,
        slug,
      }),
    });
  }

  /**
   * 4. Retrieve post details
   */
  async getPost(postId: string) {
    return this.request<{ success: boolean; data: { post: any } }>(`/api/v1/posts/${postId}`);
  }

  /**
   * 5. Get application analytics & browser-local session metrics
   */
  async getAnalytics() {
    return this.request<{
      success: boolean;
      data: Record<string, unknown>;
    }>("/api/v1/analytics");
  }
}
```

---

## 🐍 Zero-Dependency Python Client

Save as `memeflow_client.py`:

```python
import os
import uuid
import json
import urllib.request
import urllib.error

class MemeFlowClient:
    def __init__(self, api_key=None, base_url=None):
        self.api_key = api_key or os.getenv("MEMEFLOW_API_KEY", "YOUR_MEMEFLOW_API_KEY")
        self.base_url = (base_url or os.getenv("MEMEFLOW_API_BASE_URL", "https://creator-connect-earn.lovable.app")).rstrip("/")

    def _request(self, endpoint, method="GET", payload=None):
        url = f"{self.base_url}{endpoint}"
        headers = {
            "Authorization": f"Bearer {self.api_key}",
            "X-API-Key": self.api_key,
            "Accept": "application/json",
        }

        data_bytes = None
        if payload is not None:
            headers["Content-Type"] = "application/json"
            if method == "POST":
                headers["Idempotency-Key"] = str(uuid.uuid4())
            data_bytes = json.dumps(payload).encode("utf-8")

        req = urllib.request.Request(url, data=data_bytes, headers=headers, method=method)
        try:
            with urllib.request.urlopen(req) as resp:
                return json.loads(resp.read().decode("utf-8"))
        except urllib.error.HTTPError as e:
            err_text = e.read().decode("utf-8")
            raise RuntimeError(f"MemeFlow API Error ({e.code}): {err_text}")

    def create_post(self, title, caption="", media_url=None, media=None):
        payload = {
            "title": title,
            "caption": caption,
            "media_url": media_url,
            "media": media or []
        }
        return self._request("/api/v1/posts", method="POST", payload=payload)

    def create_partner_session(self, partner_content_id, media_url, content_version="1.0", action="view", title=None):
        payload = {
            "partner_content_id": partner_content_id,
            "content_version": content_version,
            "action": action,
            "title": title,
            "media_url": media_url
        }
        return self._request("/api/v1/partner/content", method="POST", payload=payload)

    def create_smart_link(self, post_id, slug=None, return_url=None):
        payload = {
            "post_id": post_id,
        }
        if slug is not None:
            payload["slug"] = slug
        if return_url is not None:
            payload["return_url"] = return_url
        return self._request("/api/v1/links", method="POST", payload=payload)
```

---

## 🎵 BandLab Studio Multi-Track Audio Standard

When registering audio descriptors, preserve studio quality by attaching `audio_metadata`:

```json
{
  "media_url": "https://cdn.example.com/audio/lead-vocal-stems.wav",
  "media_type": "audio",
  "file_name": "lead-vocal-stems.wav",
  "audio_metadata": {
    "isMultiTrack": true,
    "sampleRate": 48000,
    "bitDepth": 24,
    "channelCount": 2,
    "tempoBpm": 128
  }
}
```

---

## ⚡ Webhook Receiver Verification (`t=<timestamp>,v1=<signature>`)

MemeFlow signs webhook deliveries using `X-MemeFlow-Signature: t=<timestamp>,v1=<signature>` where `v1` is the hex HMAC-SHA256 digest over `${timestamp}.${rawBody}`:

```typescript
import crypto from "crypto";
import express from "express";

const app = express();

app.post("/webhook/memeflow", express.raw({ type: "application/json" }), (req, res) => {
  const signatureHeader = (req.headers["x-memeflow-signature"] as string) || "";
  const signingSecret = process.env.MEMEFLOW_WEBHOOK_SECRET || "";
  const rawBody = req.body.toString("utf-8");

  const parts = Object.fromEntries(
    signatureHeader.split(",").map((part) => part.trim().split("=")),
  );
  const timestamp = parts.t;
  const signature = parts.v1;

  if (!timestamp || !signature || !signingSecret) {
    return res.status(401).send("Missing webhook signature or secret");
  }

  const signedPayload = `${timestamp}.${rawBody}`;
  const computed = crypto.createHmac("sha256", signingSecret).update(signedPayload).digest("hex");

  if (
    computed.length !== signature.length ||
    !crypto.timingSafeEqual(Buffer.from(computed), Buffer.from(signature))
  ) {
    return res.status(401).send("Invalid webhook signature");
  }

  const event = JSON.parse(rawBody);
  console.log("Verified MemeFlow Event:", event.event_type, event.data);
  res.status(200).json({ received: true });
});
```

---

## 🌐 Quick cURL Examples

```bash
# 1. Verify Credentials
curl -H "Authorization: Bearer YOUR_MEMEFLOW_API_KEY" \
     "https://creator-connect-earn.lovable.app/api/v1/auth/verify"

# 2. Create Post
curl -X POST "https://creator-connect-earn.lovable.app/api/v1/posts" \
     -H "Authorization: Bearer YOUR_MEMEFLOW_API_KEY" \
     -H "Content-Type: application/json" \
     -H "Idempotency-Key: $(uuidgen)" \
     -d '{
       "title": "BandLab Multi-Track Audio Master",
       "category": "Music",
       "media": [
         {
           "media_url": "https://cdn.example.com/audio/master.wav",
           "media_type": "audio",
           "file_name": "master.wav"
         }
       ]
     }'
```
