# How to Filter and Search Article Content by Tags Using the RealWorld API

> Learn how to filter and search article content by tags using the RealWorld API. Easily find articles with specific tags via a simple GET request and tag query parameter.

- Repository: [Thinkster/realworld](https://github.com/gothinkster/realworld)
- Tags: how-to-guide
- Published: 2026-02-28

---

**You can filter articles by specific tags in the RealWorld API by sending a GET request to `/api/articles` with a `tag` query parameter, which returns a paginated list of articles whose `tagList` array contains the requested tag.**

The gothinkster/realworld repository provides a **RESTful API specification** that implements Medium-style social blogging functionality. To filter and search article content by specific tags using the RealWorld API, clients interact with dedicated endpoints defined in the OpenAPI specification that handle tag discovery, article creation with metadata, and server-side filtering.

## API Architecture and OpenAPI Specification

The tag filtering mechanism is formally defined in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml), which specifies how the backend interprets query parameters and structures article responses. The specification defines the `tag` parameter as a simple string (`type: string`) that the backend uses to filter against each article's `tagList` array.

### The tag Query Parameter Definition

According to lines 181-195 in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml), the `GET /api/articles` endpoint accepts an optional `tag` query parameter. When provided, the backend implementation (found in concrete examples under `apps/*/src/`) constructs database queries such as `WHERE tagList @> [tag]` to return only articles containing the specified tag in their metadata.

## Retrieving Available Tags

Before filtering, clients typically fetch the catalog of existing tags to populate user interfaces or validate search terms.

### GET /api/tags Endpoint

The `GET /api/tags` endpoint returns a JSON object containing a `tags` array with every tag currently used across all articles. No authentication is required for this request. This endpoint is defined at lines 442-452 in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml) and validated by the test suite in `specs/api/hurl/tags.hurl`.

```bash
curl "https://api.realworld.show/api/tags"

```

The response format follows this structure:

```json
{
  "tags": ["react", "javascript", "nodejs", "angular"]
}

```

## Filtering Articles by Specific Tags

### Basic Tag Filtering

To filter and search article content by specific tags, append the `tag` parameter to the articles endpoint. The server returns a `MultipleArticlesResponse` object containing an `articles` array and an `articlesCount` integer indicating the total matches.

```bash
curl "https://api.realworld.show/api/articles?tag=javascript"

```

### Combining Filters and Pagination

The same endpoint supports chaining the `tag` filter with other query parameters. According to the `parameters` block in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml), you can combine `tag` with `author` and `favorited` filters, along with pagination controls.

The pagination parameters, defined at lines 5-12 in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml), include:
- **`limit`**: Defaults to 20, controls articles per page
- **`offset`**: Defaults to 0, controls pagination offset

```bash

# Filter by tag and author with pagination

curl "https://api.realworld.show/api/articles?tag=angular&author=john&limit=10&offset=0"

```

## Creating Articles with Tags

To ensure articles appear in tag-filtered searches, they must be created with a `tagList` array. When posting to `POST /api/articles` (defined at lines 221-235 in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml)), include the `tagList` field containing an array of strings.

```bash
curl -X POST "https://api.realworld.show/api/articles" \
  -H "Content-Type: application/json" \
  -H "Authorization: Token YOUR_TOKEN" \
  -d '{
    "article": {
      "title": "Working with RealWorld Tags",
      "description": "How to use tag filtering",
      "body": "Article content here...",
      "tagList": ["api", "tutorial", "backend"]
    }
  }'

```

Once created, these tags automatically become available via `GET /api/tags` and filterable through the articles endpoint.

## Client Implementation Examples

### cURL

```bash

# Get articles with specific tag

curl "https://api.realworld.show/api/articles?tag=javascript"

# With pagination (first 5 results)

curl "https://api.realworld.show/api/articles?tag=javascript&limit=5&offset=0"

```

### JavaScript Fetch API

```javascript
async function fetchArticlesByTag(tag, limit = 20, offset = 0) {
  const url = new URL('https://api.realworld.show/api/articles');
  url.searchParams.append('tag', tag);
  url.searchParams.append('limit', limit);
  url.searchParams.append('offset', offset);

  const response = await fetch(url, {
    method: 'GET'
    // Authentication not required for tag filtering
  });

  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const data = await response.json();
  return data; // { articles: [...], articlesCount: N }
}

// Example usage
fetchArticlesByTag('react', 10, 0).then(console.log);

```

### Python requests

```python
import requests

def get_articles_by_tag(tag, limit=20, offset=0):
    url = 'https://api.realworld.show/api/articles'
    params = {'tag': tag, 'limit': limit, 'offset': offset}
    
    resp = requests.get(url, params=params)
    resp.raise_for_status()
    return resp.json()  # {"articles": [...], "articlesCount": N}

# Example

if __name__ == '__main__':
    data = get_articles_by_tag('nodejs', limit=5)
    print(data)

```

## Key Source Files and Implementation Details

The RealWorld API tag filtering mechanism is implemented across these authoritative source files:

- **[`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml)**: Lines 181-195 define the `tag` query parameter for the articles endpoint, while lines 442-452 define the `/tags` endpoint structure. Lines 5-12 specify the global pagination schema.

- **`specs/api/hurl/tags.hurl`**: Integration test suite that registers a user, creates an article with tags, and verifies that `GET /api/tags` returns the created tags correctly.

- **[`apps/documentation/src/content/docs/specifications/backend/endpoints.md`](https://github.com/gothinkster/realworld/blob/main/apps/documentation/src/content/docs/specifications/backend/endpoints.md)**: Human-readable documentation describing the `GET /articles?tag=` filter behavior and response formats.

- **`apps/*/src/`**: Concrete backend implementations (such as [`apps/api/src/router/articles.ts`](https://github.com/gothinkster/realworld/blob/main/apps/api/src/router/articles.ts) in the Node.js example) that parse the `tag` query parameter and execute database filters server-side.

## Summary

- **Tag Discovery**: Use `GET /api/tags` to retrieve all available tags without authentication, as defined in the OpenAPI specification.
- **Filtering**: Append `?tag=TAGNAME` to `/api/articles` to filter and search article content by specific tags using the RealWorld API.
- **Pagination**: Combine `limit` (default 20) and `offset` (default 0) parameters to handle large result sets efficiently.
- **Chaining**: Mix `tag` with `author` and `favorited` filters for precise queries, all processed server-side.
- **Storage**: Tags are stored in the `tagList` array within article objects, with backend implementations querying this array to filter results.

## Frequently Asked Questions

### Do I need authentication to filter articles by tags?

No, the tag filter itself does not require authentication. The `GET /api/articles?tag=` endpoint is publicly accessible according to the OpenAPI specification in [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml). However, authentication via JWT token is required to create articles with tags or to access personalized feed endpoints.

### Can I filter by multiple tags at once?

The current API specification defines the `tag` parameter as a single string value. To filter by multiple tags, you must make separate API requests for each tag or retrieve a broader result set and perform client-side filtering. The backend checks each article's `tagList` array for exact matches against the single provided tag string.

### How are tags stored in the RealWorld database?

Tags are stored as an array of strings in the `tagList` field of each article object, as defined in the `NewArticleRequest` schema at lines 221-235 of [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml). Backend implementations under `apps/*/src/` typically map this to database array types (such as PostgreSQL arrays or JSON fields) and use containment operators to filter articles where the `tagList` contains the requested tag.

### What is the default pagination limit when filtering by tags?

The default `limit` is 20 articles per request, with `offset` defaulting to 0. These pagination parameters are defined in the global parameters section at lines 5-12 of [`specs/api/openapi.yml`](https://github.com/gothinkster/realworld/blob/main/specs/api/openapi.yml) and apply consistently across all article list endpoints, including filtered results by tag, author, or favorited status.