or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

blog-management.mdclient-setup.mdindex.mdpost-operations.mdtagged-and-generic.mduser-operations.md

tagged-and-generic.mddocs/

0

# Tagged Content and Generic Requests

1

2

Methods for accessing tagged content across Tumblr and making arbitrary API requests for unsupported endpoints or custom implementations.

3

4

## Capabilities

5

6

### Tagged Posts

7

8

Retrieves public posts tagged with a specific tag from across the Tumblr platform.

9

10

```javascript { .api }

11

/**

12

* Gets posts tagged with the specified tag

13

* @param tag - The tag on the posts you'd like to retrieve

14

* @param params - Optional query parameters for filtering and pagination

15

* @returns Promise resolving to tagged posts and metadata

16

*/

17

taggedPosts(tag: string, params?: TaggedPostsParams): Promise<any>;

18

19

interface TaggedPostsParams {

20

/** Return posts before this timestamp */

21

before?: number;

22

/** The number of results to return: 1–20, inclusive */

23

limit?: number;

24

/** Response filter: 'text' for text only, 'raw' for raw HTML */

25

filter?: 'text' | 'raw';

26

/** Additional tag parameters can be passed as key-value pairs */

27

[key: string]: any;

28

}

29

```

30

31

**Usage Examples:**

32

33

```javascript

34

// Get posts tagged with 'photography'

35

const photoTagged = await client.taggedPosts('photography', {

36

limit: 20,

37

});

38

photoTagged.response.forEach(post => {

39

console.log(`${post.blog_name}: ${post.type} post`);

40

});

41

42

// Get posts with timestamp filtering

43

const olderPosts = await client.taggedPosts('nature', {

44

before: 1640995200, // Unix timestamp

45

limit: 10,

46

});

47

48

// Get posts with text filter

49

const textOnlyPosts = await client.taggedPosts('poetry', {

50

filter: 'text',

51

limit: 15,

52

});

53

54

// Get posts with additional parameters

55

const taggedPosts = await client.taggedPosts('art', {

56

limit: 20,

57

sort: 'recent',

58

// Any additional parameters are passed through

59

});

60

```

61

62

### Generic GET Request

63

64

Performs arbitrary GET requests to any Tumblr API endpoint with automatic authentication and parameter handling.

65

66

```javascript { .api }

67

/**

68

* Performs a GET request

69

* @param apiPath - URL path for the request (e.g., '/v2/user/info')

70

* @param params - Optional query parameters to include in the request

71

* @returns Promise resolving to API response data

72

*/

73

getRequest(apiPath: string, params?: Record<string, any>): Promise<any>;

74

```

75

76

**Usage Examples:**

77

78

```javascript

79

// Make a custom GET request

80

const customResponse = await client.getRequest('/v2/user/info');

81

82

// GET request with parameters

83

const blogInfo = await client.getRequest('/v2/blog/example/info', {

84

'fields[blogs]': 'name,title,posts',

85

});

86

87

// Access experimental or undocumented endpoints

88

const experimentalData = await client.getRequest('/v2/experimental/feature', {

89

param1: 'value1',

90

param2: 'value2',

91

});

92

93

// GET request with array parameters

94

const postsWithTags = await client.getRequest('/v2/blog/example/posts', {

95

tag: ['tag1', 'tag2'],

96

limit: 10,

97

});

98

```

99

100

### Generic POST Request

101

102

Performs arbitrary POST requests to any Tumblr API endpoint with automatic authentication and data handling.

103

104

```javascript { .api }

105

/**

106

* Performs a POST request

107

* @param apiPath - URL path for the request (e.g., '/v2/user/follow')

108

* @param params - Optional parameters to include in the request body

109

* @returns Promise resolving to API response data

110

*/

111

postRequest(apiPath: string, params?: Record<string, any>): Promise<any>;

112

```

113

114

**Usage Examples:**

115

116

```javascript

117

// Make a custom POST request

118

await client.postRequest('/v2/user/follow', {

119

url: 'https://example.tumblr.com',

120

});

121

122

// POST request with complex data

123

await client.postRequest('/v2/blog/myblog/posts', {

124

type: 'text',

125

title: 'Custom Post',

126

body: 'Posted via generic POST request',

127

tags: 'custom,api',

128

});

129

130

// POST request with file data (form-data will be used automatically)

131

await client.postRequest('/v2/blog/myblog/posts', {

132

type: 'photo',

133

caption: 'Uploaded via POST request',

134

data: fs.createReadStream('./image.jpg'),

135

});

136

137

// POST request to experimental endpoints

138

await client.postRequest('/v2/experimental/action', {

139

action: 'test',

140

parameters: {

141

key1: 'value1',

142

key2: 'value2',

143

},

144

});

145

```

146

147

### Generic PUT Request

148

149

Performs arbitrary PUT requests to any Tumblr API endpoint with automatic authentication and data handling.

150

151

```javascript { .api }

152

/**

153

* Performs a PUT request

154

* @param apiPath - URL path for the request (e.g., '/v2/blog/myblog/posts/123')

155

* @param params - Optional parameters to include in the request body

156

* @returns Promise resolving to API response data

157

*/

158

putRequest(apiPath: string, params?: Record<string, any>): Promise<any>;

159

```

160

161

**Usage Examples:**

162

163

```javascript

164

// Update a resource with PUT

165

await client.putRequest('/v2/blog/myblog/posts/12345678901', {

166

title: 'Updated Title',

167

body: 'Updated content',

168

});

169

170

// PUT request with complex data structures

171

await client.putRequest('/v2/blog/myblog/settings', {

172

title: 'My Updated Blog',

173

description: 'New blog description',

174

privacy: 'public',

175

});

176

177

// PUT request for NPF post editing

178

await client.putRequest('/v2/blog/myblog/posts/12345678901', {

179

json: JSON.stringify({

180

content: [

181

{

182

type: 'text',

183

text: 'Updated NPF content',

184

},

185

],

186

}),

187

});

188

```

189

190

## Request Data Handling

191

192

The generic request methods automatically handle different types of data:

193

194

### Query Parameters (GET)

195

```javascript

196

// Arrays are converted to indexed parameters

197

await client.getRequest('/v2/blog/example/posts', {

198

tag: ['first', 'second'], // Becomes tag[0]=first&tag[1]=second

199

});

200

201

// Objects are flattened appropriately

202

await client.getRequest('/v2/endpoint', {

203

simple: 'value',

204

nested: { key: 'value' }, // Handled appropriately for the endpoint

205

});

206

```

207

208

### Request Body Data (POST/PUT)

209

```javascript

210

// JSON data (default for simple objects)

211

await client.postRequest('/v2/endpoint', {

212

title: 'Simple string',

213

count: 42,

214

flag: true,

215

});

216

217

// Form-data (automatic when ReadStream objects are present)

218

await client.postRequest('/v2/blog/myblog/posts', {

219

type: 'photo',

220

data: fs.createReadStream('./image.jpg'), // Triggers form-data

221

caption: 'Photo caption',

222

});

223

224

// NPF with JSON field (special form-data handling)

225

await client.postRequest('/v2/blog/myblog/posts', {

226

json: JSON.stringify({ // Special NPF format

227

content: [{ type: 'text', text: 'Hello' }],

228

}),

229

media: fs.createReadStream('./file.jpg'),

230

});

231

```

232

233

### Authentication Handling

234

235

Generic requests automatically handle authentication based on client configuration:

236

237

```javascript

238

// No authentication (public endpoints)

239

const publicClient = tumblr.createClient();

240

await publicClient.getRequest('/v2/blog/example/info');

241

242

// API key authentication

243

const apiKeyClient = tumblr.createClient({

244

consumer_key: 'your_api_key',

245

});

246

await apiKeyClient.getRequest('/v2/blog/example/posts'); // Adds ?api_key=...

247

248

// OAuth authentication

249

const oauthClient = tumblr.createClient({

250

consumer_key: 'key',

251

consumer_secret: 'secret',

252

token: 'token',

253

token_secret: 'token_secret',

254

});

255

await oauthClient.postRequest('/v2/user/follow', { url: 'example' }); // Adds OAuth headers

256

```

257

258

## Error Handling

259

260

Generic request methods provide comprehensive error handling:

261

262

```javascript

263

try {

264

const response = await client.getRequest('/v2/nonexistent/endpoint');

265

} catch (error) {

266

console.error('API Error:', error.message);

267

// Error messages include HTTP status and API error details

268

// Example: "API error: 404 Not Found"

269

}

270

271

// Handle malformed API responses

272

try {

273

const response = await client.postRequest('/v2/endpoint', { data: 'test' });

274

} catch (error) {

275

if (error.message.includes('malformed API response')) {

276

console.error('API returned invalid JSON');

277

}

278

}

279

```

280

281

## Common Use Cases

282

283

### Accessing New API Features

284

```javascript

285

// Use generic requests to access newly released API features

286

// before they're added to the library

287

const newFeature = await client.getRequest('/v2/new/feature', {

288

experimental: true,

289

});

290

```

291

292

### Custom Error Handling

293

```javascript

294

// Implement custom retry logic or error handling

295

async function robustRequest(client, path, params) {

296

let attempts = 3;

297

while (attempts > 0) {

298

try {

299

return await client.getRequest(path, params);

300

} catch (error) {

301

attempts--;

302

if (attempts === 0) throw error;

303

await new Promise(resolve => setTimeout(resolve, 1000));

304

}

305

}

306

}

307

```

308

309

### Batch Operations

310

```javascript

311

// Combine multiple requests for batch operations

312

const blogNames = ['blog1', 'blog2', 'blog3'];

313

const blogInfos = await Promise.all(

314

blogNames.map(name => client.getRequest(`/v2/blog/${name}/info`))

315

);

316

```

317

318

## Authentication Requirements

319

320

- **No authentication**: Some public endpoints work without credentials

321

- **API key authentication**: Most read operations require `consumer_key`

322

- **OAuth authentication**: Write operations and private data require full OAuth credentials