Skip to content
adscapi

Creatives

Upload one image creative to a single platform. Secret-absent and unsupported platforms no-op into an honest result — nothing throws. Meta ships a real image upload today; Pinterest and Reddit are deferred.

Signature

ts
import { uploadCreative, CREATIVE_PLATFORMS } from 'adscapi';

const result: CreativeResult = await uploadCreative({
  platform: 'meta' | 'pinterest' | 'reddit',
  imageUrl?: string,           // a fetchable image URL
  imageBytes?: Uint8Array,     // alternative to imageUrl
  name?: string,               // optional filename (Meta wants an extension)
  secrets?: AdscapiSecrets,    // default: process.env
});

Options — CreativeUpload

FieldTypeNotes
platform'meta' | 'pinterest' | 'reddit'See support table below
imageUrlstring?Fetchable URL. Meta has no url param — adscapi downloads and sends base64 bytes
imageBytesUint8Array?Raw bytes alternative to imageUrl. At least one of the two is required
namestring?Filename. Meta requires an extension (e.g. hero.jpg); defaults from the URL path or creative.jpg
secretsAdscapiSecrets?Defaults to process.env

CREATIVE_PLATFORMS

PlatformSupportNotes
metaimage-uploadUploads to the ad account’s adimages edge. Returns the image hash as id. Needs META_AD_ACCOUNT_ID + META_CAPI_TOKEN (with ads_management scope)
pinterestdeferredv5/media is documented for video only; image path is pin creation (ad-object creation, out of v1 scope)
redditdeferredAds API v3 has no media upload endpoint; creatives take an externally-hosted media_url at post creation

Return — CreativeResult

ts
type CreativeResult = {
  platform: 'meta' | 'pinterest' | 'reddit';
  ok: boolean;
  id?: string;      // platform-side creative/image id (Meta: the image hash)
  error?: string;   // e.g. 'no image provided', HTTP failures
  skipped?: string; // 'secrets absent' | 'deferred — …'
};

Example

ts
import { uploadCreative, CREATIVE_PLATFORMS } from 'adscapi';

// What does each platform actually support today?
console.log(CREATIVE_PLATFORMS);
// {
//   meta:      { support: 'image-upload', note: '…', doc: '…' },
//   pinterest: { support: 'deferred',    note: '…', doc: '…' },
//   reddit:    { support: 'deferred',    note: '…', doc: '…' },
// }

const result = await uploadCreative({
  platform: 'meta',
  imageUrl: 'https://cdn.example.com/ads/hero.jpg',
  name: 'hero.jpg',
});

if (result.ok) {
  console.log('image hash', result.id); // Meta returns the ad-image hash
} else if (result.skipped) {
  console.warn('skipped:', result.skipped); // 'secrets absent' or 'deferred — …'
} else {
  console.error(result.error);
}
shell
# Same path via the CLI
npx adscapi creatives upload --platform meta --image https://cdn.example.com/hero.jpg

Related