Skip to content

REST API Quick Start

Five steps: verify your key, pick a brand, pick a collection, create a draft, confirm it landed. Nothing here publishes, queues, or schedules anything.

You need:

  • A Nuelink account with at least one brand and one collection.
  • An API key from Settings → API.
  • curl, or any server-side HTTP client.

Put the key in an environment variable. Not in source code, not in browser JavaScript, not in a URL, not in a log:

Terminal window
read -rs NUELINK_API_KEY && export NUELINK_API_KEY
export NUELINK_API_BASE="https://app.nuelink.com/api/public/v1"

read -rs does not echo what you type, so the key never appears on screen or as a literal in your history. In CI, inject NUELINK_API_KEY from your secret manager instead.

Terminal window
# confirm it is set without printing it
[ -n "$NUELINK_API_KEY" ] && echo "key loaded"
Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
"$NUELINK_API_BASE/me"
{
"status": "success",
"data": {
"id": "user_id",
"name": "Example User",
"joinedAt": "2026-01-01T00:00:00.000000Z",
"timezone": "UTC"
}
}

GET /auth returns the same response, if you’d rather your code say “validate” than “who am I”.

Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
"$NUELINK_API_BASE/brands?page=1&per_page=100"

Save the id of the brand you want:

Terminal window
export BRAND_ID="1001"
Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
"$NUELINK_API_BASE/brands/$BRAND_ID/collections?page=1&per_page=100"
Terminal window
export COLLECTION_ID="2001"

Look at each collection’s channels before you choose. The collection decides where a non-draft post publishes. If you want a target that can’t reach anyone while you’re testing, create a collection with no channels, see Endpoints.

Terminal window
curl --fail-with-body --silent --show-error \
-X POST \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
"$NUELINK_API_BASE/brands/$BRAND_ID/collections/$COLLECTION_ID/posts" \
--data '{
"title": "API quick-start draft",
"caption": "This draft was created through the Nuelink API.",
"publishMode": "DRAFT"
}'
{
"status": "success",
"data": {
"id": 4733837,
"message": "Post created successfully"
}
}

The create response tells you a post exists. It doesn’t tell you what kind. Read it back:

Terminal window
curl --fail-with-body --silent --show-error \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
"$NUELINK_API_BASE/brands/$BRAND_ID/collections/$COLLECTION_ID/posts?page=1&per_page=100"

Find your post ID and check:

{
"postingType": "DRAFT",
"status": "DRAFT",
"postDate": null
}

If postDate isn’t null, something scheduled it. Fix that before you write any more code.

The multipart field name is media:

Terminal window
curl --fail-with-body --silent --show-error \
-X POST \
-H "Authorization: Bearer $NUELINK_API_KEY" \
-H "Accept: application/json" \
"$NUELINK_API_BASE/brands/$BRAND_ID/media" \
-F "media=@./launch.jpg"

Pass the returned string id into the post’s media array as {"id": "..."}. GET /media also returns opaque string IDs that can be used in post creation. If the file is already at a public URL, skip the upload and pass {"url": "..."} instead. See Endpoints.

  • Resolve brand and collection IDs at runtime. Never hardcode an ID from an example.
  • Default uncertain publishing intent to DRAFT.
  • Treat QUEUE, SCHEDULE, and IMMEDIATE as explicit decisions a human made.
  • Don’t auto-retry a create after a timeout or a 5xx. See Errors.
  • Respect the rate-limit headers and the brand’s timezone.
  • Keep the key in a server-side secret manager.

Next: Authentication, Errors, Endpoints.