0
# Post Management
1
2
Complete post lifecycle management including creation of all Tumblr post types (text, photo, quote, link, chat, audio, video), editing, reblogging, deletion, and notes retrieval. These methods require authentication and appropriate permissions for the target blog.
3
4
## Capabilities
5
6
### Post Creation
7
8
Create posts of all Tumblr post types with comprehensive parameter support and file upload capabilities.
9
10
#### Text Posts
11
12
Create text-based content with markdown or HTML formatting support.
13
14
```python { .api }
15
def create_text(self, blogname: str, **kwargs) -> dict:
16
"""
17
Create a text post.
18
19
Args:
20
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
21
22
Parameters:
23
title (str, optional): Post title (supports HTML/markdown)
24
body (str, optional): Post body content (supports HTML/markdown)
25
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
26
tags (list, optional): List of tag strings
27
tweet (str, optional): Custom tweet text
28
date (str, optional): GMT date and time for the post
29
format (str, optional): Content format ('html' or 'markdown')
30
slug (str, optional): URL slug for the post
31
32
Returns:
33
dict: Created post information including ID
34
"""
35
```
36
37
Usage example:
38
39
```python
40
# Create a simple text post
41
client.create_text(
42
'my-blog.tumblr.com',
43
title='Hello World',
44
body='This is my first post using **PyTumblr**!',
45
state='published',
46
tags=['python', 'tumblr', 'first-post'],
47
format='markdown'
48
)
49
```
50
51
#### Photo Posts
52
53
Create photo posts and photosets with local file upload or external URL support.
54
55
```python { .api }
56
def create_photo(self, blogname: str, **kwargs) -> dict:
57
"""
58
Create a photo post or photoset.
59
60
Args:
61
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
62
63
Parameters:
64
caption (str, optional): Photo caption (supports HTML/markdown)
65
link (str, optional): Click-through URL for the photo
66
source (str, optional): External photo URL (use this OR data, not both)
67
data (str or list, optional): Local file path(s) for upload
68
photoset_layout (str, optional): Layout for photoset
69
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
70
tags (list, optional): List of tag strings
71
tweet (str, optional): Custom tweet text
72
date (str, optional): GMT date and time for the post
73
format (str, optional): Content format ('html' or 'markdown')
74
slug (str, optional): URL slug for the post
75
76
Returns:
77
dict: Created post information including ID
78
"""
79
```
80
81
Usage examples:
82
83
```python
84
# Create photo post from URL
85
client.create_photo(
86
'my-blog.tumblr.com',
87
source='https://example.com/image.jpg',
88
caption='Beautiful sunset!',
89
tags=['photography', 'sunset']
90
)
91
92
# Upload local photo
93
client.create_photo(
94
'my-blog.tumblr.com',
95
data='/path/to/photo.jpg',
96
caption='My latest artwork',
97
state='queue'
98
)
99
100
# Create photoset from multiple files
101
client.create_photo(
102
'my-blog.tumblr.com',
103
data=['/path/to/photo1.jpg', '/path/to/photo2.jpg'],
104
caption='Photo collection from my trip',
105
photoset_layout='1,1'
106
)
107
```
108
109
#### Quote Posts
110
111
Create inspirational or quoted content with source attribution.
112
113
```python { .api }
114
def create_quote(self, blogname: str, **kwargs) -> dict:
115
"""
116
Create a quote post.
117
118
Args:
119
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
120
121
Parameters:
122
quote (str, optional): The full text of the quote
123
source (str, optional): Source/attribution for the quote (supports HTML)
124
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
125
tags (list, optional): List of tag strings
126
tweet (str, optional): Custom tweet text
127
date (str, optional): GMT date and time for the post
128
format (str, optional): Content format ('html' or 'markdown')
129
slug (str, optional): URL slug for the post
130
131
Returns:
132
dict: Created post information including ID
133
"""
134
```
135
136
Usage example:
137
138
```python
139
client.create_quote(
140
'my-blog.tumblr.com',
141
quote='The only way to do great work is to love what you do.',
142
source='Steve Jobs',
143
tags=['inspiration', 'quotes']
144
)
145
```
146
147
#### Link Posts
148
149
Share external links with descriptions and thumbnails.
150
151
```python { .api }
152
def create_link(self, blogname: str, **kwargs) -> dict:
153
"""
154
Create a link post.
155
156
Args:
157
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
158
159
Parameters:
160
title (str, optional): Link title (supports HTML entities)
161
url (str, optional): The URL to link to
162
description (str, optional): Description of the linked content
163
thumbnail (str, optional): Thumbnail image URL
164
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
165
tags (list, optional): List of tag strings
166
tweet (str, optional): Custom tweet text
167
date (str, optional): GMT date and time for the post
168
format (str, optional): Content format ('html' or 'markdown')
169
slug (str, optional): URL slug for the post
170
171
Returns:
172
dict: Created post information including ID
173
"""
174
```
175
176
Usage example:
177
178
```python
179
client.create_link(
180
'my-blog.tumblr.com',
181
title='Amazing Search Engine',
182
url='https://duckduckgo.com',
183
description='Privacy-focused search that doesn\'t track you.',
184
tags=['privacy', 'search', 'tools']
185
)
186
```
187
188
#### Chat Posts
189
190
Create conversation or dialogue posts with formatted exchanges.
191
192
```python { .api }
193
def create_chat(self, blogname: str, **kwargs) -> dict:
194
"""
195
Create a chat post.
196
197
Args:
198
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
199
200
Parameters:
201
title (str, optional): Chat title
202
conversation (str, optional): The conversation text (no HTML, dialogue labels)
203
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
204
tags (list, optional): List of tag strings
205
tweet (str, optional): Custom tweet text
206
date (str, optional): GMT date and time for the post
207
format (str, optional): Content format ('html' or 'markdown')
208
slug (str, optional): URL slug for the post
209
210
Returns:
211
dict: Created post information including ID
212
"""
213
```
214
215
Usage example:
216
217
```python
218
chat_text = """Alice: Did you see the latest Python release?
219
Bob: Yes! The new features are amazing.
220
Alice: I especially love the pattern matching.
221
Bob: Same here, makes code so much cleaner."""
222
223
client.create_chat(
224
'my-blog.tumblr.com',
225
title='Python Discussion',
226
conversation=chat_text,
227
tags=['python', 'programming', 'chat']
228
)
229
```
230
231
#### Audio Posts
232
233
Share audio content from external sources or file uploads.
234
235
```python { .api }
236
def create_audio(self, blogname: str, **kwargs) -> dict:
237
"""
238
Create an audio post.
239
240
Args:
241
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
242
243
Parameters:
244
caption (str, optional): Audio caption
245
external_url (str, optional): External audio URL (use this OR data, not both)
246
data (str, optional): Local audio file path for upload
247
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
248
tags (list, optional): List of tag strings
249
tweet (str, optional): Custom tweet text
250
date (str, optional): GMT date and time for the post
251
format (str, optional): Content format ('html' or 'markdown')
252
slug (str, optional): URL slug for the post
253
254
Returns:
255
dict: Created post information including ID
256
"""
257
```
258
259
Usage examples:
260
261
```python
262
# Share external audio (SoundCloud, etc.)
263
client.create_audio(
264
'my-blog.tumblr.com',
265
external_url='https://soundcloud.com/artist/track',
266
caption='Check out this amazing track!'
267
)
268
269
# Upload local audio file
270
client.create_audio(
271
'my-blog.tumblr.com',
272
data='/path/to/song.mp3',
273
caption='My latest composition',
274
tags=['music', 'original']
275
)
276
```
277
278
#### Video Posts
279
280
Share video content via embeds or file uploads.
281
282
```python { .api }
283
def create_video(self, blogname: str, **kwargs) -> dict:
284
"""
285
Create a video post.
286
287
Args:
288
blogname (str): Blog URL to post to (e.g., 'my-blog.tumblr.com')
289
290
Parameters:
291
caption (str, optional): Video caption
292
embed (str, optional): HTML embed code for the video (use this OR data, not both)
293
data (str, optional): Local video file path for upload
294
state (str, optional): Post state ('published', 'draft', 'queue', 'private')
295
tags (list, optional): List of tag strings
296
tweet (str, optional): Custom tweet text
297
date (str, optional): GMT date and time for the post
298
format (str, optional): Content format ('html' or 'markdown')
299
slug (str, optional): URL slug for the post
300
301
Returns:
302
dict: Created post information including ID
303
"""
304
```
305
306
Usage examples:
307
308
```python
309
# Embed YouTube video
310
client.create_video(
311
'my-blog.tumblr.com',
312
embed='https://www.youtube.com/watch?v=dQw4w9WgXcQ',
313
caption='Classic video that never gets old'
314
)
315
316
# Upload local video
317
client.create_video(
318
'my-blog.tumblr.com',
319
data='/path/to/video.mp4',
320
caption='Behind the scenes footage',
321
tags=['video', 'bts']
322
)
323
```
324
325
### Post Modification
326
327
Edit existing posts, reblog content, and delete posts.
328
329
```python { .api }
330
def edit_post(self, blogname: str, **kwargs) -> dict:
331
"""
332
Edit an existing post.
333
334
Args:
335
blogname (str): Blog URL containing the post
336
337
Parameters:
338
id (int, required): Post ID to edit
339
type (str, optional): Post type (helps with validation)
340
[All post-type-specific parameters available based on type]
341
342
Returns:
343
dict: Updated post information
344
"""
345
346
def reblog(self, blogname: str, **kwargs) -> dict:
347
"""
348
Reblog a post.
349
350
Args:
351
blogname (str): Blog URL to reblog to
352
353
Parameters:
354
id (int, required): Post ID to reblog
355
reblog_key (str, required): Reblog key from original post
356
comment (str, optional): Comment to add to the reblog
357
[All common post parameters available]
358
359
Returns:
360
dict: Reblogged post information
361
"""
362
363
def delete_post(self, blogname: str, id: int) -> dict:
364
"""
365
Delete a post.
366
367
Args:
368
blogname (str): Blog URL containing the post
369
id (int): Post ID to delete
370
371
Returns:
372
dict: Deletion confirmation
373
"""
374
```
375
376
Usage examples:
377
378
```python
379
# Edit a text post
380
client.edit_post(
381
'my-blog.tumblr.com',
382
id=123456789,
383
type='text',
384
title='Updated Title',
385
body='Updated content'
386
)
387
388
# Reblog with comment
389
client.reblog(
390
'my-blog.tumblr.com',
391
id=987654321,
392
reblog_key='abc123def',
393
comment='Great post! Thanks for sharing.',
394
tags=['reblog', 'interesting']
395
)
396
397
# Delete a post
398
client.delete_post('my-blog.tumblr.com', 123456789)
399
```
400
401
### Post Notes and Interactions
402
403
Retrieve notes (likes, reblogs, replies) for posts.
404
405
```python { .api }
406
def notes(self, blogname: str, id: str, **kwargs) -> dict:
407
"""
408
Get notes for a specific post.
409
410
Args:
411
blogname (str): Blog URL containing the post
412
id (str): Post ID
413
414
Parameters:
415
mode (str, optional): Undocumented parameter
416
before_timestamp (str, optional): Get notes before this timestamp
417
418
Returns:
419
dict: Post notes and pagination info
420
"""
421
```
422
423
Usage example:
424
425
```python
426
# Get notes for a post
427
notes = client.notes('example-blog.tumblr.com', '123456789')
428
429
# Paginate through notes
430
if notes.get('_links', {}).get('next'):
431
next_params = notes['_links']['next']['query_params']
432
more_notes = client.notes(
433
'example-blog.tumblr.com',
434
'123456789',
435
before_timestamp=next_params['before_timestamp']
436
)
437
```
438
439
### Tagged Content Discovery
440
441
Find posts across Tumblr by tags.
442
443
```python { .api }
444
def tagged(self, tag: str, **kwargs) -> dict:
445
"""
446
Get posts with a specific tag from across Tumblr.
447
448
Args:
449
tag (str): Tag to search for
450
451
Parameters:
452
before (int, optional): Unix timestamp to get posts before
453
limit (int, optional): Number of posts to return (default: 20, max: 20)
454
filter (str, optional): Post format ('html', 'text', 'raw')
455
api_key (str, optional): For public access without authentication
456
457
Returns:
458
dict: Tagged posts from across Tumblr
459
"""
460
```
461
462
Usage example:
463
464
```python
465
# Find posts tagged with specific term
466
tagged_posts = client.tagged('photography', limit=20)
467
468
# Get older posts with pagination
469
older_posts = client.tagged('art', before=1234567890)
470
```
471
472
## Common Parameters
473
474
All post creation methods support these common parameters:
475
476
```python
477
common_params = {
478
'state': 'published', # 'published', 'draft', 'queue', 'private'
479
'tags': ['tag1', 'tag2'], # List of strings
480
'tweet': 'Custom tweet text [URL]', # Custom tweet
481
'date': '2023-12-01 12:00:00 GMT', # GMT date/time
482
'format': 'html', # 'html' or 'markdown'
483
'slug': 'custom-url-slug' # URL slug
484
}
485
```
486
487
## Error Handling
488
489
Post management methods return detailed error information:
490
491
```python
492
response = client.create_text('my-blog', title='Test', body='Content')
493
if response.get('meta', {}).get('status') != 201: # 201 = Created
494
print(f"Error: {response.get('meta', {}).get('msg')}")
495
if 'errors' in response.get('response', {}):
496
for error in response['response']['errors']:
497
print(f"Field error: {error}")
498
```
499
500
Common error scenarios:
501
- **400 Bad Request**: Invalid parameters or missing required fields
502
- **401 Unauthorized**: Authentication required or invalid credentials
503
- **403 Forbidden**: No permission to post to this blog
504
- **413 Payload Too Large**: File upload exceeds size limits
505
- **429 Too Many Requests**: Rate limit exceeded