Reddit API
Schedule and automate Reddit posts with RelayAPI — text posts, link posts, image posts, galleries, subreddit targeting, and flair support.
Quick Reference
| Property | Value |
|---|---|
| Platform key | reddit |
| Auth method | OAuth 2.0 |
| Title limit | 300 characters (required, cannot edit after posting) |
| Body text limit | 40,000 characters |
| Images per post | 1 (single), multiple (gallery) |
| Videos per post | Not supported via third-party API |
| Image formats | JPEG, PNG, GIF |
| Image max size | 20 MB |
| Post types | Text/Self, Link, Image, Gallery |
| Scheduling | Yes |
| Analytics | Limited (upvotes, comments only) |
SDK source — TypeScript · Python · Go · Java · REST API
Before You Start
Reddit is fundamentally different from every other platform. Each subreddit is independently moderated with its own rules. What works in one subreddit may get you banned in another. Always check subreddit rules before posting. The post title is permanent and cannot be edited after posting. Many subreddits require flair — posts without it will be rejected. Video uploads are not supported for third-party API apps. New accounts are heavily restricted by karma and account age requirements.
Quick Start
Post to a subreddit:
import Relay from '@relayapi/sdk';
const client = new Relay();
const post = await client.posts.create({
content: 'Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people\'s code',
targets: ['reddit'],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'learnprogramming'
}
}
});
console.log(post.id); // post_abc123from relay import Relay
client = Relay()
post = client.posts.create(
content='Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people\'s code',
targets=['reddit'],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'learnprogramming'
}
}
)
print(post.id) # post_abc123client := relaygo.NewClient()
post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people's code"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "learnprogramming",
},
}),
})RelayClient client = RelayOkHttpClient.fromEnv();
PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people's code")
.addTarget("reddit")
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "learnprogramming"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people'\''s code",
"targets": ["reddit"],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "learnprogramming"
}
}
}'Content Types
Text/Self Post
The first line of content becomes the title, and the rest becomes the body. Reddit Markdown is supported in the body text.
const post = await client.posts.create({
content: 'Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people\'s code',
targets: ['reddit'],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'learnprogramming'
}
}
});post = client.posts.create(
content='Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people\'s code',
targets=['reddit'],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'learnprogramming'
}
}
)post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people's code"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "learnprogramming",
},
}),
})PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people's code")
.addTarget("reddit")
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "learnprogramming"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Tips for learning a new programming language\n\n1. Start with the official tutorial\n2. Build a small project immediately\n3. Read other people'\''s code",
"targets": ["reddit"],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "learnprogramming"
}
}
}'You can also provide the title explicitly using target_options.reddit.title. If not provided, the first line of content is used as the title.
Link Post
Share a URL. The title is the first line of content, and the url field creates a link post instead of a text post.
const post = await client.posts.create({
content: 'Interesting article about modern API design patterns',
targets: ['reddit'],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'programming',
url: 'https://example.com/api-design-article'
}
}
});post = client.posts.create(
content='Interesting article about modern API design patterns',
targets=['reddit'],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'programming',
'url': 'https://example.com/api-design-article'
}
}
)post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("Interesting article about modern API design patterns"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "programming",
"url": "https://example.com/api-design-article",
},
}),
})PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("Interesting article about modern API design patterns")
.addTarget("reddit")
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "programming",
"url", "https://example.com/api-design-article"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Interesting article about modern API design patterns",
"targets": ["reddit"],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "programming",
"url": "https://example.com/api-design-article"
}
}
}'Image Post
Single image post with a title.
const post = await client.posts.create({
content: 'Check out this view from my hike!',
targets: ['reddit'],
media: [
{ url: 'https://cdn.example.com/hiking-photo.jpg', type: 'image' }
],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'hiking'
}
}
});post = client.posts.create(
content='Check out this view from my hike!',
targets=['reddit'],
media=[
{'url': 'https://cdn.example.com/hiking-photo.jpg', 'type': 'image'}
],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'hiking'
}
}
)post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("Check out this view from my hike!"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
Media: relaygo.F([]relaygo.PostNewParamsMedia{{
URL: relaygo.F("https://cdn.example.com/hiking-photo.jpg"),
Type: relaygo.F(relaygo.PostNewParamsMediaTypeImage),
}}),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "hiking",
},
}),
})PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("Check out this view from my hike!")
.addTarget("reddit")
.addMedia(PostCreateParams.Media.builder()
.url("https://cdn.example.com/hiking-photo.jpg")
.type(PostCreateParams.Media.Type.IMAGE)
.build())
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "hiking"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Check out this view from my hike!",
"targets": ["reddit"],
"media": [
{"url": "https://cdn.example.com/hiking-photo.jpg", "type": "image"}
],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "hiking"
}
}
}'Gallery Post (Multiple Images)
Upload multiple images as a gallery. Not all subreddits support gallery posts.
const post = await client.posts.create({
content: 'My weekend woodworking project - start to finish',
targets: ['reddit'],
media: [
{ url: 'https://cdn.example.com/step1.jpg', type: 'image' },
{ url: 'https://cdn.example.com/step2.jpg', type: 'image' },
{ url: 'https://cdn.example.com/finished.jpg', type: 'image' }
],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'woodworking'
}
}
});post = client.posts.create(
content='My weekend woodworking project - start to finish',
targets=['reddit'],
media=[
{'url': 'https://cdn.example.com/step1.jpg', 'type': 'image'},
{'url': 'https://cdn.example.com/step2.jpg', 'type': 'image'},
{'url': 'https://cdn.example.com/finished.jpg', 'type': 'image'}
],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'woodworking'
}
}
)post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("My weekend woodworking project - start to finish"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
Media: relaygo.F([]relaygo.PostNewParamsMedia{
{URL: relaygo.F("https://cdn.example.com/step1.jpg"), Type: relaygo.F(relaygo.PostNewParamsMediaTypeImage)},
{URL: relaygo.F("https://cdn.example.com/step2.jpg"), Type: relaygo.F(relaygo.PostNewParamsMediaTypeImage)},
{URL: relaygo.F("https://cdn.example.com/finished.jpg"), Type: relaygo.F(relaygo.PostNewParamsMediaTypeImage)},
}),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "woodworking",
},
}),
})PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("My weekend woodworking project - start to finish")
.addTarget("reddit")
.addMedia(PostCreateParams.Media.builder()
.url("https://cdn.example.com/step1.jpg")
.type(PostCreateParams.Media.Type.IMAGE)
.build())
.addMedia(PostCreateParams.Media.builder()
.url("https://cdn.example.com/step2.jpg")
.type(PostCreateParams.Media.Type.IMAGE)
.build())
.addMedia(PostCreateParams.Media.builder()
.url("https://cdn.example.com/finished.jpg")
.type(PostCreateParams.Media.Type.IMAGE)
.build())
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "woodworking"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "My weekend woodworking project - start to finish",
"targets": ["reddit"],
"media": [
{"url": "https://cdn.example.com/step1.jpg", "type": "image"},
{"url": "https://cdn.example.com/step2.jpg", "type": "image"},
{"url": "https://cdn.example.com/finished.jpg", "type": "image"}
],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "woodworking"
}
}
}'Post with Flair
Many subreddits require flair on every post. You can list available flairs for a subreddit via the RelayAPI accounts endpoint.
const post = await client.posts.create({
content: 'What is your favorite programming language?',
targets: ['reddit'],
scheduled_at: 'now',
target_options: {
reddit: {
subreddit: 'socialmedia',
flair_id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
}
}
});post = client.posts.create(
content='What is your favorite programming language?',
targets=['reddit'],
scheduled_at='now',
target_options={
'reddit': {
'subreddit': 'socialmedia',
'flair_id': 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
}
}
)post, err := client.Posts.New(context.TODO(), relaygo.PostNewParams{
Content: relaygo.F("What is your favorite programming language?"),
Targets: relaygo.F([]string{"reddit"}),
ScheduledAt: relaygo.F("now"),
TargetOptions: relaygo.F(map[string]interface{}{
"reddit": map[string]interface{}{
"subreddit": "socialmedia",
"flair_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
},
}),
})PostCreateResponse post = client.posts().create(PostCreateParams.builder()
.content("What is your favorite programming language?")
.addTarget("reddit")
.scheduledAt("now")
.targetOptions(PostCreateParams.TargetOptions.builder()
.putAdditionalProperty("reddit", JsonValue.from(Map.of(
"subreddit", "socialmedia",
"flair_id", "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
)))
.build())
.build());curl -X POST https://api.relayapi.dev/v1/posts \
-H "Authorization: Bearer $RELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "What is your favorite programming language?",
"targets": ["reddit"],
"scheduled_at": "now",
"target_options": {
"reddit": {
"subreddit": "socialmedia",
"flair_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}
}'To get available flairs for a subreddit, use GET /v1/accounts/{id}/reddit-flairs?subreddit=NAME. Many subreddits reject posts without flair.
Media Requirements
Images
| Property | Requirement |
|---|---|
| Max per post | 1 (single), multiple (gallery) |
| Formats | JPEG, PNG, GIF |
| Max file size | 20 MB |
| Recommended | 1200 x 628 px |
| Aspect ratios | Flexible (16:9, 4:3, 1:1, 9:16 all work) |
Videos
| Property | Requirement |
|---|---|
| Support | Not supported via third-party API |
| Workaround | Upload to YouTube or Imgur, then create a link post |
target_options Fields
All fields go inside target_options.reddit on your post request.
| Field | Type | Description |
|---|---|---|
content | string | Override content for Reddit specifically |
media | object[] | Override media for Reddit specifically |
subreddit | string | Target subreddit without the r/ prefix. Required. |
title | string | Post title (max 300 chars). Falls back to first line of content. Cannot be edited after posting. |
url | string | URL for link posts. If provided, creates a link post instead of a text post. |
flair_id | string | Post flair ID. Required by some subreddits. |
force_self | boolean | Force a text/self post even when media or a URL is provided |
Auto-Retry Behavior
RelayAPI automatically retries failed Reddit posts in certain scenarios:
- Link post in text-only subreddit — automatically retries as a text/self post with the URL included in the body.
- Missing required flair — automatically tries the first available flair for the subreddit.
Common Errors
| Error | Cause | Fix |
|---|---|---|
| SUBREDDIT_NOTALLOWED: only trusted members | Subreddit restricts posting to trusted members | Build karma, engage with the community, or choose a different subreddit. |
| NO_SELFS: doesn't allow text posts | Subreddit only accepts links or images | Provide a url or attach an image instead. |
| SUBMIT_VALIDATION_FLAIR_REQUIRED | Flair is required by the subreddit | Fetch available flairs and provide a flair_id. |
| SUBREDDIT_NOEXIST | Typo in subreddit name or subreddit is private | Check spelling. Do not include the r/ prefix. |
| AI-generated content not allowed | Subreddit bans AI-generated content | Write original content or choose a different subreddit. |
| Rate limited | Reddit rate limit hit | New accounts are limited to ~10 posts/day. Space posts further apart. |
Known Quirks
- Title is permanent — the post title cannot be edited after posting. Double-check before submitting.
- Video uploads not supported for third-party apps. Upload to YouTube/Imgur and create a link post.
- Each subreddit has unique, independent rules — moderation varies wildly between communities.
- New accounts are heavily restricted — karma requirements and account age gates apply.
- Reddit Markdown supported in body text for formatting.
- Gallery posts not supported by all subreddits — check subreddit rules.
- Auto-retry behavior — link posts that fail in text-only subreddits are automatically retried as self posts.
- Flair auto-retry — if flair is required but not provided, RelayAPI tries the first available flair.
Automations
Commercial use of Reddit's API requires explicit written approval via the Responsible Builder Policy. OAuth clients are rate-limited to ~100 QPM. Polling-based (no webhooks).
Triggers
| Type | Fires on |
|---|---|
reddit_comment | Comment on your post / reply to your comment |
reddit_mention | u/username mention |
reddit_new_post | New post in a watched subreddit |
reddit_modmail | Modmail conversation |
reddit_dm | Direct private message |
Send nodes
Base: https://oauth.reddit.com. All endpoints expect form-encoded bodies + a custom User-Agent.
| Node | Endpoint | Required fields |
|---|---|---|
reddit_reply_to_comment | POST /api/comment | text, thing_id (fullname, e.g. t1_xyz) |
reddit_send_pm | POST /api/compose | to, text, optional subject |
reddit_reply_modmail | POST /api/mod/conversations/{id} | body, conversation_id |
reddit_submit_post | POST /api/submit | subreddit, title, either text (self) or url (link) |
Found something wrong? Help us improve this page.