# Monetize your directory with strategic ad placements
Source: https://docs.directify.app/ads/manage-ads
Learn how to create, customize, and manage advertisements in your directory with flexible placement options and styling controls
Directify's advertising system allows you to monetize your directory through strategic ad placements while maintaining a professional user experience. Create custom ads with flexible styling options and precise placement controls.
## Ad Types
### Default Ad Content
Create simple, effective ads with structured components:
* **Title** - Eye-catching headline with customizable styling
* **Description** - Compelling ad copy with formatting options
* **Background Image** - Visual appeal with editor and aspect ratio controls
* **Link** - Call-to-action button with custom styling and "sponsored" badge
### Rich Text Editor
Use markdown-powered content creation for:
* Structured, formatted content
* High-resolution images and videos
* YouTube/Vimeo embed support
* Professional content presentation
### HTML Editor
Full control over ad content with:
* Custom HTML/CSS implementation
* Advanced styling capabilities
* Complete design freedom
* Professional developer features
## Ad Placement Options
### Hero Everywhere
* Displays on all pages in the hero section
* Maximum visibility and impact
* Ideal for brand awareness campaigns
### Hero Category
* Shows only on specific category pages
* Targeted advertising for niche audiences
* Select multiple categories for broader reach
### Hero Listing
* Appears on individual listing pages
* Highly targeted placement
* Perfect for related products/services
### First Listing
* Positioned as the first item in listing grids
* Seamless integration with organic content
* Native advertising approach
## Styling Customization
### Title Styling
* **Font Size** - From extra small to 7X-large
* **Color** - Custom color picker for brand alignment
* **Font Weight** - Normal, bold, semi-bold, or light
* **Font Style** - Normal or italic options
* **Custom CSS** - Tailwind classes for advanced styling
### Description Styling
* **Font Size** - Flexible sizing options
* **Color** - Custom color selection
* **Font Weight** - Multiple weight options
* **Font Style** - Normal or italic
* **Custom CSS** - Advanced styling capabilities
### Image Styling
* **Height** - Responsive height options (96px to 384px)
* **Border Radius** - From none to full circular
* **Border Width** - Customizable border thickness
* **Border Color** - Brand-aligned border colors
* **Background Color** - Fallback background colors
* **Background Position** - Precise image positioning
* **Background Size** - Cover, contain, or auto sizing
* **Custom CSS** - Additional styling control
### Link Styling
* **Link Text** - Customizable call-to-action text
* **Font Styling** - Size, weight, and style options
* **Border Options** - Radius, width, and color
* **Background Color** - Button background customization
* **Text Color** - Button text color
* **Sponsored Badge** - Customizable "sponsored" indicator
* **Badge Colors** - Text and background color options
* **Custom CSS** - Advanced button styling
## Ad Management
### Visibility Controls
* **Active Status** - Enable/disable ads without deletion
* **Category Targeting** - Select specific categories for Hero Category ads
* **Listing Targeting** - Choose specific listings for Hero Listing ads
### Performance Features
* **Name Field** - Internal organization and identification
* **Creation Date** - Track ad implementation timeline
* **Easy Editing** - Quick modifications without recreating ads
## Best Practices
1. **Visual Consistency** - Match ad styling to your directory's design
2. **Clear Value Proposition** - Ensure ad content provides clear value
3. **Strategic Placement** - Choose placement based on user behavior
4. **Mobile Optimization** - Test ad appearance on mobile devices
5. **Performance Monitoring** - Track ad effectiveness and adjust accordingly
Always maintain transparency with sponsored content by keeping the "sponsored" badge visible and properly configured.
## Integration Tips
### Design Harmony
* Use colors that complement your directory theme
* Maintain consistent typography with your brand
* Ensure ads don't overwhelm organic content
### User Experience
* Position ads strategically without disrupting navigation
* Maintain clear distinction between ads and directory content
* Test placement effectiveness with user feedback
***
Customize your directory's overall design
Set up monetization through paid listings
# Autonomous Directify Agent
Source: https://docs.directify.app/ai-tools/agent
Run a self-managing AI agent that maintains your Directify directory on a schedule — built on OpenClaw and the Directify API.
## What is the agent?
The **Directify Agent** is a pre-configured [OpenClaw](https://openclaw.ai) agent that manages your directory autonomously. Unlike the [MCP server](/ai-tools/mcp-server) (which you chat with on demand), the agent can run on a schedule and perform recurring work — for example, importing scraped listings, tidying categories, or keeping content fresh — and remembers context between runs.
This is an advanced, self-hosted setup for users comfortable with the command line. If you just want to manage your directory by chatting, start with the [MCP Server](/ai-tools/mcp-server) instead.
## Prerequisites
* [Node.js 18+](https://nodejs.org)
* An [API token](/api-integration/authentication) (**Settings → API**) and your **Directory ID**
* The Directify agent files (the `directify-agent` package)
## Setup
```bash theme={null}
npm install -g openclaw
openclaw setup
```
Copy the Directify agent files into a workspace folder and register it with OpenClaw:
```bash theme={null}
mkdir -p ~/clawd-directify
cp -r ./directify-agent/* ~/clawd-directify/
# First time only — copy the example gateway config
cp ~/clawd-directify/openclaw.example.json ~/.openclaw/openclaw.json
```
If you already have an `~/.openclaw/openclaw.json`, add the agent to your existing `agents.list` instead:
```json theme={null}
{
"id": "directify",
"name": "Directify Agent",
"workspace": "~/clawd-directify"
}
```
Edit `~/clawd-directify/TOOLS.md` and fill in your details:
```markdown theme={null}
- **Base URL:** `https://directify.app/api`
- **API Key:** `df_live_abc123...`
- **Directory ID:** `42`
```
Edit `USER.md` with your name and directory so the agent's output matches your voice:
```markdown theme={null}
- **Name:** John
- **Directory:** Chicago Restaurants
- **URL:** https://chicagorestaurants.com
```
```bash theme={null}
openclaw gateway restart
```
Then message your agent, e.g. *"Show me all my listings"*.
## What it can do
The agent has access to the same actions as the [API](/api-integration/authentication) and [MCP server](/ai-tools/mcp-server) — listings, categories, tags, custom fields, organizers, articles, and pages. Because it runs on a schedule and keeps memory, it's well suited to recurring jobs:
* *"Every morning, check my source site and import any new listings."*
* *"Keep all listings in the 'Old' category set to draft."*
* *"Tag every published listing without a website URL as 'incomplete'."*
For one-off or interactive work, the [MCP server](/ai-tools/mcp-server) is simpler. Reach for the autonomous agent when you want hands-off, scheduled maintenance.
# Directify CLI — Manage Your Directory from the Terminal
Source: https://docs.directify.app/ai-tools/cli
Install and connect the directify command-line tool. Manage listings, categories, tags, custom fields, organizers, articles, and pages from your terminal or scripts.
## What is the CLI?
`directify` is the official command-line tool. It wraps the [Directify REST API](/api-integration/authentication) so you can manage your directory from your terminal, shell scripts, or CI pipelines — no AI required. It's ideal for power users and automation.
## Install
Requires [Node.js 18+](https://nodejs.org).
```bash theme={null}
npm install -g directify-cli
```
Or run it without installing, using `npx`:
```bash theme={null}
npx directify-cli --help
```
## Connect
In your Directify dashboard, go to **Settings → API** and click the **Key icon** to generate a token.
```bash theme={null}
directify auth login YOUR_API_TOKEN
```
Your token is stored locally so you only do this once.
```bash theme={null}
# Find your directory IDs
directify directories list
# Set the default so you don't pass --directory every time
directify config set-directory 123
```
## Start managing
```bash theme={null}
# Listings
directify listings list
directify listings create --name "Bella Trattoria" --description "Authentic Italian cuisine" --categories 1,5 --organizers 8
# Categories & tags
directify categories create --title "Italian" --icon "🍝"
directify tags create --title "Featured"
# Custom fields
directify fields create --label "Price Range" --type select --options "$,$$,$$$" --filterable
directify fields list
# Articles & pages
directify articles list
directify pages create --title "About Us" --placement navbar
```
Every command supports `--help`, and most accept `-d, --directory ` to target a specific directory (overriding the default) and `--json` for machine-readable output.
The CLI mirrors the API one-to-one. If a command errors with a validation message, it's coming straight from the API — see [Authentication → Error Responses](/api-integration/authentication) for what each status code means.
## Common command groups
| Group | Commands |
| ------------- | -------------------------------------------------------------------- |
| `auth` | `login`, `logout`, `status` |
| `config` | `set-directory`, `get-directory` |
| `directories` | `list` |
| `listings` | `list`, `get`, `create`, `update`, `delete`, `exists`, `bulk-create` |
| `categories` | `list`, `get`, `create`, `update`, `delete` |
| `tags` | `list`, `get`, `create`, `update`, `delete` |
| `fields` | `list`, `get`, `create`, `update`, `delete` |
| `organizers` | `list`, `get`, `create`, `update`, `delete` |
| `articles` | `list`, `get`, `create`, `update`, `delete`, `toggle` |
| `pages` | `list`, `get`, `create`, `update`, `delete`, `toggle` |
Run `directify --help` (or `directify --help`) to see every command and option.
Want to manage your directory by chatting with an AI assistant instead? See the [MCP Server guide](/ai-tools/mcp-server).
# Connect the MCP Server to Claude, Cursor & More
Source: https://docs.directify.app/ai-tools/mcp-server
Step-by-step setup for the Directify MCP server. Connect Claude Desktop, Claude Code, Cursor, or any MCP-compatible AI assistant and manage your directory in plain English.
## What is the MCP server?
The **Model Context Protocol (MCP)** is an open standard that lets AI assistants use external tools. The Directify MCP server exposes your directory's management actions — creating listings, categories, tags, custom fields, organizers, articles, and pages — as tools the AI can call.
Once connected, you simply chat:
> *"Add a listing called Bella Trattoria, Italian category, price range \$\$, and link it to the Acme Events organizer."*
…and the assistant does it for you.
## Video walkthrough
## Step 1 — Get your credentials
In your Directify dashboard, go to **Settings → API** and click the **Key icon** to generate a token. Copy it — it's shown only once.
Find it in the dashboard URL (`/app/{directory_id}/...`). It's optional in most setups — if you skip it, the assistant will ask which directory to use, or you can say *"list my directories"*.
## Step 2 — Choose remote or local
Use our hosted server at `https://mcp.directify.app/mcp`. **No installation** — nothing to install or update.
Run the `directify-mcp` npm package on your own machine. Requires [Node.js 18+](https://nodejs.org).
## Step 3 — Add it to your AI client
Replace `YOUR_API_TOKEN` with your token and `YOUR_DIRECTORY_ID` with your directory's ID in the examples below.
Open **Settings → Developer → Edit Config**, or edit the file directly:
* **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
* **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**Remote (recommended):**
```json theme={null}
{
"mcpServers": {
"directify": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.directify.app/mcp",
"--header", "Authorization:Bearer YOUR_API_TOKEN",
"--header", "X-Directory-ID:YOUR_DIRECTORY_ID"
]
}
}
}
```
**Local:**
```json theme={null}
{
"mcpServers": {
"directify": {
"command": "npx",
"args": ["-y", "directify-mcp"],
"env": {
"DIRECTIFY_API_TOKEN": "YOUR_API_TOKEN",
"DIRECTIFY_DIRECTORY_ID": "YOUR_DIRECTORY_ID"
}
}
}
}
```
**Fully quit and reopen Claude Desktop** (not just close the window) for the change to take effect.
Run one command from your terminal.
**Remote (recommended):**
```bash theme={null}
claude mcp add directify -- npx -y mcp-remote \
https://mcp.directify.app/mcp \
--header "Authorization:Bearer YOUR_API_TOKEN" \
--header "X-Directory-ID:YOUR_DIRECTORY_ID"
```
**Local:**
```bash theme={null}
claude mcp add directify \
--env DIRECTIFY_API_TOKEN=YOUR_API_TOKEN \
--env DIRECTIFY_DIRECTORY_ID=YOUR_DIRECTORY_ID \
-- npx -y directify-mcp
```
Verify it's connected with `claude mcp list`.
Create or edit `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for all projects).
**Remote (recommended):**
```json theme={null}
{
"mcpServers": {
"directify": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://mcp.directify.app/mcp",
"--header", "Authorization:Bearer YOUR_API_TOKEN",
"--header", "X-Directory-ID:YOUR_DIRECTORY_ID"
]
}
}
}
```
**Local:**
```json theme={null}
{
"mcpServers": {
"directify": {
"command": "npx",
"args": ["-y", "directify-mcp"],
"env": {
"DIRECTIFY_API_TOKEN": "YOUR_API_TOKEN",
"DIRECTIFY_DIRECTORY_ID": "YOUR_DIRECTORY_ID"
}
}
}
}
```
Then open **Cursor Settings → MCP** and confirm `directify` shows a green dot.
Any MCP-compatible client that supports remote servers can connect via the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge using the same pattern:
```bash theme={null}
npx -y mcp-remote https://mcp.directify.app/mcp \
--header "Authorization:Bearer YOUR_API_TOKEN" \
--header "X-Directory-ID:YOUR_DIRECTORY_ID"
```
For clients that natively support remote MCP over OAuth (such as Claude.ai web connectors), add `https://mcp.directify.app/mcp` as the server URL and complete the sign-in prompt instead of passing a token header.
The `X-Directory-ID` / `DIRECTIFY_DIRECTORY_ID` value is **optional**. Omit it to let the assistant work across all your directories — it'll ask which one to use, or you can call `list_directories`.
## Step 4 — Try it out
Restart your AI client, then ask:
> *"List my Directify directories."*
> *"Create a listing called 'Blue Bottle Coffee' in the Cafés category."*
> *"What custom fields does this directory have? Add a filterable 'Price Range' select field with options \$, \$\$, \$\$\$."*
> *"Create an organizer 'Acme Events' and link these three listings to it."*
## What can it do?
The MCP server exposes tools for every major part of your directory:
| Area | Examples |
| ----------------- | ------------------------------------------------------------------------------------------------------ |
| **Directories** | list directories you own |
| **Listings** | list, get, create, update, delete, bulk-create, check-exists, set custom field values, link organizers |
| **Categories** | list, get, create, update, delete |
| **Tags** | list, get, create, update, delete |
| **Custom Fields** | list, get, create, update, delete field definitions |
| **Organizers** | list, get, create, update, delete |
| **Articles** | list, get, create, update, delete, toggle published |
| **Custom Pages** | list, get, create, update, delete, toggle published |
## Troubleshooting
* Make sure you have **Node.js 18+** installed (`node --version`) — `npx` needs it.
* **Fully quit and reopen** Claude Desktop (closing the window isn't enough).
* Double-check the JSON is valid (no trailing commas, matched brackets).
Your API token is missing, mistyped, or revoked. Generate a fresh one at **Settings → API** and update your config. The header format is exactly `Authorization:Bearer YOUR_API_TOKEN` (note the single space after `Bearer`).
The token must belong to the account that **owns** the directory, and the `X-Directory-ID` must be one of your directories. Ask the assistant to *"list my directories"* to see valid IDs.
The API allows **120 requests per minute** per directory. For large bulk jobs, ask the assistant to batch the work or slow down.
Prefer the terminal or want to script things? Use the [Directify CLI](/ai-tools/cli) instead — same actions, no AI required.
# Manage Directify with AI & Automation
Source: https://docs.directify.app/ai-tools/overview
Connect Claude, Cursor, the command line, or an autonomous agent to your Directify directory. Create listings, manage categories, publish articles, and more — in plain English or from your terminal.
## Overview
Beyond the dashboard, you can manage your Directify directory programmatically — including with AI assistants like **Claude**. There are three ways to connect, all built on the [Directify REST API](/api-integration/authentication):
Connect Claude, Cursor, or any MCP-compatible AI assistant. Manage your directory in plain English.
The `directify` command-line tool. Great for scripts, automation, and power users.
A self-running agent that manages your directory on a schedule, built on OpenClaw.
### Which one should I use?
| You want to… | Use |
| -------------------------------------------------------------------------- | ----------------------------------------------- |
| Chat with Claude to create/edit listings, categories, custom fields, etc. | **[MCP Server](/ai-tools/mcp-server)** |
| Run commands or scripts from your terminal / CI | **[CLI](/ai-tools/cli)** |
| Have an agent that works autonomously (e.g. scrape & import on a schedule) | **[Autonomous Agent](/ai-tools/agent)** |
| Call the API directly from your own code | **[REST API](/api-integration/authentication)** |
## Video walkthrough
A step-by-step walkthrough of connecting the MCP server to Claude and managing your directory by chat.
## Before you start
All three methods need the same two things:
In your Directify dashboard, go to **Settings → API** and click the **Key icon** to generate a token. Copy it somewhere safe — you won't be able to see it again.
Treat your API token like a password. Anyone with it can manage your directories. You can revoke and regenerate it any time from **Settings → API**.
The numeric ID of the directory you want to manage. Find it in the dashboard URL when viewing a directory (`/app/{directory_id}/...`), or ask the AI to *"list my Directify directories"* once connected.
Requests are limited to **120 per minute** per directory — plenty for AI-driven workflows. See [Authentication](/api-integration/authentication) for details.
# Articles
Source: https://docs.directify.app/api-integration/articles
Manage blog articles through the Directify API - create, read, update, and delete articles with full CRUD operations and SEO support.
## Articles
In Directify, **articles** are blog posts that appear in your directory's blog section. These can be written in HTML or Markdown format and include full SEO metadata support. The API uses slug-based storage to prevent duplicate articles and automatically generates SEO-friendly URLs.
### Get Directory Articles
Retrieve all articles for a specific directory with pagination.
```http theme={null}
GET /api/directories/{directory_id}/articles
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Query Parameters:**
* `page` (integer, optional): Page number for pagination (default: 1)
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"title": "Getting Started with React",
"slug": "getting-started-with-react",
"content": "
Getting Started with React
React is a powerful JavaScript library...
",
"markdown": "# Getting Started with React\n\nReact is a powerful JavaScript library...",
"is_markdown": true,
"active": true,
"published_at": "2024-01-15T10:30:00.000000Z",
"thumbnail_url": "https://example.com/images/react-tutorial.jpg",
"thumbnail_alt_text": "React tutorial screenshot",
"categories": ["tutorial", "react", "frontend"],
"blog_buster_article_id": null,
"seo": {
"id": 1,
"title": "Getting Started with React - Complete Tutorial",
"description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"keywords": "react, tutorial, javascript, frontend",
"og_title": "Getting Started with React - Complete Tutorial",
"og_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"og_image": "https://example.com/images/react-tutorial-og.jpg",
"twitter_title": "Getting Started with React - Complete Tutorial",
"twitter_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"twitter_image": "https://example.com/images/react-tutorial-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/getting-started-with-react/",
"robots": "index, follow",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/getting-started-with-react/",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
],
"links": {
"first": "https://your-directify-domain.com/api/directories/1/articles?page=1",
"last": "https://your-directify-domain.com/api/directories/1/articles?page=3",
"prev": null,
"next": "https://your-directify-domain.com/api/directories/1/articles?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 3,
"per_page": 100,
"to": 100,
"total": 250
}
}
```
### Get Single Article
Retrieve a specific article by ID.
```http theme={null}
GET /api/directories/{directory_id}/articles/{article_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `article_id` (integer, required): The ID of the article
**Response:**
```json theme={null}
{
"data": {
"id": 1,
"title": "Getting Started with React",
"slug": "getting-started-with-react",
"content": "
Getting Started with React
React is a powerful JavaScript library...
",
"markdown": "# Getting Started with React\n\nReact is a powerful JavaScript library...",
"is_markdown": true,
"active": true,
"published_at": "2024-01-15T10:30:00.000000Z",
"thumbnail_url": "https://example.com/images/react-tutorial.jpg",
"thumbnail_alt_text": "React tutorial screenshot",
"categories": ["tutorial", "react", "frontend"],
"blog_buster_article_id": null,
"seo": {
"id": 1,
"title": "Getting Started with React - Complete Tutorial",
"description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"keywords": "react, tutorial, javascript, frontend",
"og_title": "Getting Started with React - Complete Tutorial",
"og_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"og_image": "https://example.com/images/react-tutorial-og.jpg",
"twitter_title": "Getting Started with React - Complete Tutorial",
"twitter_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"twitter_image": "https://example.com/images/react-tutorial-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/getting-started-with-react/",
"robots": "index, follow",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/getting-started-with-react/",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
}
```
### Check Article Exists
Check if an article with a specific slug already exists in the directory.
```http theme={null}
POST /api/directories/{directory_id}/articles/exists
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"slug": "getting-started-with-react"
}
```
**Request Body Fields:**
* `slug` (string, required): The article slug to check for existence
**Response (Article exists):**
```json theme={null}
{
"message": "Article already exists in this directory"
}
```
**Response (Article doesn't exist):**
```json theme={null}
{
"message": "Article does not exist in this directory"
}
```
### Create Article
Create a new article in the directory. The API uses `updateOrCreate` based on slug to prevent duplicates.
```http theme={null}
POST /api/directories/{directory_id}/articles
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"title": "Advanced React Patterns",
"slug": "advanced-react-patterns",
"content": "
Advanced React Patterns
Learn advanced patterns in React...
",
"markdown": "# Advanced React Patterns\n\nLearn advanced patterns in React...",
"active": true,
"published_at": "2024-01-20T14:00:00.000000Z",
"thumbnail_url": "https://example.com/images/advanced-react.jpg",
"thumbnail_alt_text": "Advanced React patterns illustration",
"categories": ["advanced", "react", "patterns"],
"seo": {
"title": "Advanced React Patterns - Complete Guide",
"description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"keywords": "react, patterns, advanced, hooks, hocs",
"og_title": "Advanced React Patterns - Complete Guide",
"og_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"og_image": "https://example.com/images/advanced-react-og.jpg",
"twitter_title": "Advanced React Patterns - Complete Guide",
"twitter_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"twitter_image": "https://example.com/images/advanced-react-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/advanced-react-patterns/",
"robots": "index, follow"
}
}
```
**Request Body Fields:**
* `title` (string, required): The article title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from title if not provided
* `content` (string, optional): HTML content of the article. Required if `markdown` is not provided
* `markdown` (string, optional): Markdown content of the article. Required if `content` is not provided
* `active` (boolean, optional): Whether the article is published (default: true)
* `published_at` (datetime, optional): Publication date (default: current timestamp)
* `thumbnail_url` (string, optional): URL to the article thumbnail image (max 255 characters)
* `thumbnail_alt_text` (string, optional): Alt text for the thumbnail image (max 255 characters)
* `categories` (array, optional): Array of category strings for organizing articles
* `seo` (object, optional): SEO metadata object with the following optional fields:
* `title` (string, optional): SEO title (max 255 characters)
* `description` (string, optional): Meta description (max 500 characters)
* `keywords` (string, optional): Meta keywords (max 255 characters)
* `og_title` (string, optional): Open Graph title (max 255 characters)
* `og_description` (string, optional): Open Graph description (max 500 characters)
* `og_image` (string, optional): Open Graph image URL (max 255 characters)
* `twitter_title` (string, optional): Twitter card title (max 255 characters)
* `twitter_description` (string, optional): Twitter card description (max 500 characters)
* `twitter_image` (string, optional): Twitter card image URL (max 255 characters)
* `canonical_url` (string, optional): Canonical URL (max 255 characters)
* `robots` (string, optional): Robots meta tag value (max 255 characters)
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"title": "Advanced React Patterns",
"slug": "advanced-react-patterns",
"content": "
Advanced React Patterns
Learn advanced patterns in React...
",
"markdown": "# Advanced React Patterns\n\nLearn advanced patterns in React...",
"is_markdown": true,
"active": true,
"published_at": "2024-01-20T14:00:00.000000Z",
"thumbnail_url": "https://example.com/images/advanced-react.jpg",
"thumbnail_alt_text": "Advanced React patterns illustration",
"categories": ["advanced", "react", "patterns"],
"blog_buster_article_id": null,
"seo": {
"id": 2,
"title": "Advanced React Patterns - Complete Guide",
"description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"keywords": "react, patterns, advanced, hooks, hocs",
"og_title": "Advanced React Patterns - Complete Guide",
"og_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"og_image": "https://example.com/images/advanced-react-og.jpg",
"twitter_title": "Advanced React Patterns - Complete Guide",
"twitter_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"twitter_image": "https://example.com/images/advanced-react-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/advanced-react-patterns/",
"robots": "index, follow",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T14:00:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/advanced-react-patterns/",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T14:00:00.000000Z"
}
}
```
### Update Article
Update an existing article. If the title changes and no slug is provided, a new slug will be automatically generated.
```http theme={null}
PUT /api/directories/{directory_id}/articles/{article_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `article_id` (integer, required): The ID of the article
**Request Body:**
```json theme={null}
{
"title": "Updated: Advanced React Patterns",
"content": "
Updated: Advanced React Patterns
Updated content with new information...
",
"markdown": "# Updated: Advanced React Patterns\n\nUpdated content with new information...",
"active": true,
"categories": ["updated", "react", "patterns", "tutorial"],
"seo": {
"title": "Updated: Advanced React Patterns - Complete Guide 2024",
"description": "Master advanced React patterns with the latest updates and best practices for 2024.",
"keywords": "react, patterns, advanced, hooks, hocs, 2024"
}
}
```
**Request Body Fields:**
* `title` (string, optional): The article title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from title if title changes and no slug provided
* `content` (string, optional): HTML content of the article. Required if `markdown` is not provided
* `markdown` (string, optional): Markdown content of the article. Required if `content` is not provided
* `active` (boolean, optional): Whether the article is published
* `published_at` (datetime, optional): Publication date
* `thumbnail_url` (string, optional): URL to the article thumbnail image (max 255 characters)
* `thumbnail_alt_text` (string, optional): Alt text for the thumbnail image (max 255 characters)
* `categories` (array, optional): Array of category strings for organizing articles
* `seo` (object, optional): SEO metadata object with the following optional fields:
* `title` (string, optional): SEO title (max 255 characters)
* `description` (string, optional): Meta description (max 500 characters)
* `keywords` (string, optional): Meta keywords (max 255 characters)
* `og_title` (string, optional): Open Graph title (max 255 characters)
* `og_description` (string, optional): Open Graph description (max 500 characters)
* `og_image` (string, optional): Open Graph image URL (max 255 characters)
* `twitter_title` (string, optional): Twitter card title (max 255 characters)
* `twitter_description` (string, optional): Twitter card description (max 500 characters)
* `twitter_image` (string, optional): Twitter card image URL (max 255 characters)
* `canonical_url` (string, optional): Canonical URL (max 255 characters)
* `robots` (string, optional): Robots meta tag value (max 255 characters)
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"title": "Updated: Advanced React Patterns",
"slug": "updated-advanced-react-patterns",
"content": "
Updated: Advanced React Patterns
Updated content with new information...
",
"markdown": "# Updated: Advanced React Patterns\n\nUpdated content with new information...",
"is_markdown": true,
"active": true,
"published_at": "2024-01-20T14:00:00.000000Z",
"thumbnail_url": "https://example.com/images/advanced-react.jpg",
"thumbnail_alt_text": "Advanced React patterns illustration",
"categories": ["updated", "react", "patterns", "tutorial"],
"blog_buster_article_id": null,
"seo": {
"id": 2,
"title": "Updated: Advanced React Patterns - Complete Guide 2024",
"description": "Master advanced React patterns with the latest updates and best practices for 2024.",
"keywords": "react, patterns, advanced, hooks, hocs, 2024",
"og_title": "Advanced React Patterns - Complete Guide",
"og_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"og_image": "https://example.com/images/advanced-react-og.jpg",
"twitter_title": "Advanced React Patterns - Complete Guide",
"twitter_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"twitter_image": "https://example.com/images/advanced-react-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/advanced-react-patterns/",
"robots": "index, follow",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T15:30:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/updated-advanced-react-patterns/",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T15:30:00.000000Z"
}
}
```
### Toggle Article Status
Toggle the active status of an article (publish/unpublish).
```http theme={null}
PATCH /api/directories/{directory_id}/articles/{article_id}/toggle
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `article_id` (integer, required): The ID of the article
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"title": "Updated: Advanced React Patterns",
"slug": "updated-advanced-react-patterns",
"content": "
Updated: Advanced React Patterns
Updated content with new information...
",
"markdown": "# Updated: Advanced React Patterns\n\nUpdated content with new information...",
"is_markdown": true,
"active": false,
"published_at": "2024-01-20T14:00:00.000000Z",
"thumbnail_url": "https://example.com/images/advanced-react.jpg",
"thumbnail_alt_text": "Advanced React patterns illustration",
"categories": ["updated", "react", "patterns", "tutorial"],
"blog_buster_article_id": null,
"seo": {
"id": 2,
"title": "Updated: Advanced React Patterns - Complete Guide 2024",
"description": "Master advanced React patterns with the latest updates and best practices for 2024.",
"keywords": "react, patterns, advanced, hooks, hocs, 2024",
"og_title": "Advanced React Patterns - Complete Guide",
"og_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"og_image": "https://example.com/images/advanced-react-og.jpg",
"twitter_title": "Advanced React Patterns - Complete Guide",
"twitter_description": "Master advanced React patterns including render props, higher-order components, and custom hooks.",
"twitter_image": "https://example.com/images/advanced-react-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/advanced-react-patterns/",
"robots": "index, follow",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T15:30:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/updated-advanced-react-patterns/",
"created_at": "2024-01-20T14:00:00.000000Z",
"updated_at": "2024-01-20T15:35:00.000000Z"
}
}
```
### Get Articles by Category
Retrieve articles filtered by a specific category.
```http theme={null}
GET /api/directories/{directory_id}/articles/category/{category}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `category` (string, required): The category name to filter by
**Query Parameters:**
* `page` (integer, optional): Page number for pagination (default: 1)
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"title": "Getting Started with React",
"slug": "getting-started-with-react",
"content": "
Getting Started with React
React is a powerful JavaScript library...
",
"markdown": "# Getting Started with React\n\nReact is a powerful JavaScript library...",
"is_markdown": true,
"active": true,
"published_at": "2024-01-15T10:30:00.000000Z",
"thumbnail_url": "https://example.com/images/react-tutorial.jpg",
"thumbnail_alt_text": "React tutorial screenshot",
"categories": ["tutorial", "react", "frontend"],
"blog_buster_article_id": null,
"seo": {
"id": 1,
"title": "Getting Started with React - Complete Tutorial",
"description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"keywords": "react, tutorial, javascript, frontend",
"og_title": "Getting Started with React - Complete Tutorial",
"og_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"og_image": "https://example.com/images/react-tutorial-og.jpg",
"twitter_title": "Getting Started with React - Complete Tutorial",
"twitter_description": "Learn React from scratch with this comprehensive tutorial covering components, hooks, and best practices.",
"twitter_image": "https://example.com/images/react-tutorial-twitter.jpg",
"canonical_url": "https://your-directify-domain.com/blog/getting-started-with-react/",
"robots": "index, follow",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
"user": {
"id": 1,
"name": "John Doe",
"email": "john@example.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"article_url": "https://my-directory.com/blog/getting-started-with-react/",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
],
"links": {
"first": "https://your-directify-domain.com/api/directories/1/articles/category/tutorial?page=1",
"last": "https://your-directify-domain.com/api/directories/1/articles/category/tutorial?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"per_page": 100,
"to": 1,
"total": 1
}
}
```
### Delete Article
Delete an article from the directory.
```http theme={null}
DELETE /api/directories/{directory_id}/articles/{article_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `article_id` (integer, required): The ID of the article
**Response:**
```json theme={null}
{
"message": "Article deleted successfully"
}
```
## Key Features
### Slug-Based Storage
* Articles are stored using `updateOrCreate` based on slug to prevent duplicates
* Slugs are automatically generated from titles if not provided
* Slugs must be URL-safe (lowercase letters, numbers, and hyphens only)
* Slugs are unique within each directory
### Content Format Support
* Support for both HTML and Markdown content
* Use either `content` (HTML) or `markdown` field
* At least one content field is required (`required_without` validation)
* `is_markdown` flag indicates which format is being used
### SEO Integration
* Full SEO metadata support including Open Graph and Twitter cards
* SEO data is automatically created/updated with articles
* Canonical URLs and robots meta tags supported
* SEO data is optional but recommended for better search visibility
### Category Management
* Articles support multiple categories as an array of strings
* Categories can be used for filtering and organization
* Category filtering endpoint available for easy content discovery
### BlogBuster Integration
* Support for `blog_buster_article_id` field for external article management
* Compatible with existing BlogBuster article import workflows
* Maintains integration with automated article pulling systems
# Directify API Authentication with Sanctum Tokens
Source: https://docs.directify.app/api-integration/authentication
Authenticate requests to the Directify REST API using Laravel Sanctum personal access tokens — generate, scope, rotate, and revoke from your account.
## Authentication
All API endpoints require authentication using Laravel Sanctum. Include your API token in the Authorization header:
```bash theme={null}
Authorization: Bearer YOUR_API_TOKEN
```
To get your API token, go to your Directify dashboard and click on **Settings → API**. Then click on the **"Key" icon** to generate a new token and copy it.
## Base URL
```
https://directify.app/api
```
## Rate Limiting
API requests are limited to **120 requests per minute** per directory. This limit is designed to support automated workflows, including LLM-powered integrations that manage listings programmatically.
If you exceed the rate limit, the API returns a `429 Too Many Requests` response. Implement exponential backoff and retry logic to handle this gracefully.
## Error Responses
### Validation Errors
When request validation fails, the API returns a 422 status code with validation error details:
```json theme={null}
{
"message": "The given data was invalid.",
"errors": {
"url": [
"The url field is required."
],
"category_id": [
"The selected category id is invalid."
]
}
}
```
### Authentication Errors
When authentication fails, the API returns a 401 status code:
```json theme={null}
{
"message": "Unauthenticated."
}
```
### Authorization Errors
When the user doesn't have access to a directory, the API returns a 403 status code:
```json theme={null}
{
"message": "You do not own this directory"
}
```
### Not Found Errors
When a resource is not found, the API returns a 404 status code:
```json theme={null}
{
"message": "No query results for model [App\\Models\\Project] 123"
}
```
## Best Practices
1. **Always check if a listing exists** before creating a new one using the `/exists` endpoint
2. **Use pagination** when retrieving large lists of listings
3. **Include custom field values** in your listing creation/update requests
4. **Validate category and tag IDs** before sending them in requests
5. **Handle rate limiting** by implementing exponential backoff for failed requests
6. **Cache directory metadata** like categories, tags, and custom fields to reduce API calls
# Categories
Source: https://docs.directify.app/api-integration/categories
Manage categories for directories through the Directify API - create, read, update, and delete categories with full CRUD operations.
## Categories
Categories help you organize listings in your directory into logical groups. Categories support hierarchical structures with parent-child relationships, allowing you to create nested category trees (e.g., "Web Development" > "Frontend" > "React").
### Get Directory Categories
Retrieve all active categories for a specific directory.
```http theme={null}
GET /api/directories/{directory_id}/categories
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"title": "Web Development",
"slug": "web-development",
"description": "Tools and resources for web development",
"icon": "code",
"content": null,
"custom_icon_url": null,
"parent_id": null,
"parent_title": null,
"is_active": true,
"show_on_sidebar": true,
"order": 0,
"seo_title": null,
"seo_description": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": 2,
"title": "Frontend",
"slug": "frontend",
"description": "Frontend frameworks and libraries",
"content": null,
"icon": "browser",
"custom_icon_url": null,
"parent_id": 1,
"parent_title": "Web Development",
"is_active": true,
"show_on_sidebar": true,
"order": 1,
"seo_title": null,
"seo_description": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": 3,
"title": "Backend",
"slug": "backend",
"description": "Backend frameworks and tools",
"content": null,
"icon": "server",
"custom_icon_url": null,
"parent_id": 1,
"parent_title": "Web Development",
"is_active": true,
"show_on_sidebar": true,
"order": 2,
"seo_title": null,
"seo_description": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
]
}
```
### Get Single Category
Retrieve a specific category by ID.
```http theme={null}
GET /api/directories/{directory_id}/categories/{category_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `category_id` (integer, required): The ID of the category
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"title": "Frontend",
"slug": "frontend",
"description": "Frontend frameworks and libraries",
"content": null,
"icon": "browser",
"custom_icon_url": null,
"parent_id": 1,
"parent_title": "Web Development",
"is_active": true,
"show_on_sidebar": true,
"order": 1,
"seo_title": null,
"seo_description": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
}
```
### Create Category
Create a new category in the directory.
```http theme={null}
POST /api/directories/{directory_id}/categories
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"title": "DevOps",
"slug": "devops",
"description": "DevOps tools, CI/CD, and infrastructure",
"content": "Markdown content for the category page...",
"icon": "gear",
"custom_icon_url": "https://example.com/icons/devops.png",
"parent_id": null,
"is_active": true,
"show_on_sidebar": true,
"order": 3,
"seo_title": "DevOps Tools & Infrastructure",
"seo_description": "Browse the best DevOps tools, CI/CD pipelines, and cloud infrastructure resources.",
"head_html": ""
}
```
**Request Body Fields:**
* `title` (string, required): The category title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from title if not provided
* `description` (string, optional): Category description
* `content` (string, optional): Markdown content displayed on the category page
* `icon` (string, optional): Icon identifier (max 255 characters)
* `custom_icon_url` (url, optional): URL to a custom icon image (max 2048 characters)
* `parent_id` (integer, optional): ID of the parent category for nested hierarchies. Must reference an existing category
* `is_active` (boolean, optional): Whether the category is active (default: true)
* `show_on_sidebar` (boolean, optional): Whether to display in the sidebar navigation (default: true)
* `order` (integer, optional): Sort order for display (min: 0)
* `seo_title` (string, optional): SEO meta title (max 255 characters)
* `seo_description` (string, optional): SEO meta description (max 500 characters)
* `head_html` (string, optional): Custom HTML injected into the page `` section, e.g. hreflang tags (max 10000 characters)
**Response:**
```json theme={null}
{
"data": {
"id": 4,
"title": "DevOps",
"slug": "devops",
"description": "DevOps tools, CI/CD, and infrastructure",
"content": "Markdown content for the category page...",
"icon": "gear",
"custom_icon_url": "https://example.com/icons/devops.png",
"parent_id": null,
"parent_title": null,
"is_active": true,
"show_on_sidebar": true,
"order": 3,
"seo_title": "DevOps Tools & Infrastructure",
"seo_description": "Browse the best DevOps tools, CI/CD pipelines, and cloud infrastructure resources.",
"head_html": "",
"created_at": "2024-01-16T09:00:00.000000Z",
"updated_at": "2024-01-16T09:00:00.000000Z"
}
}
```
### Update Category
Update an existing category.
```http theme={null}
PUT /api/directories/{directory_id}/categories/{category_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `category_id` (integer, required): The ID of the category
**Request Body:**
```json theme={null}
{
"title": "DevOps & Infrastructure",
"description": "DevOps tools, CI/CD pipelines, and cloud infrastructure",
"order": 2
}
```
**Request Body Fields:**
* `title` (string, optional): The category title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only)
* `description` (string, optional): Category description
* `content` (string, optional): Markdown content displayed on the category page
* `icon` (string, optional): Icon identifier (max 255 characters)
* `custom_icon_url` (url, optional): URL to a custom icon image (max 2048 characters)
* `parent_id` (integer, optional): ID of the parent category. Must reference an existing category
* `is_active` (boolean, optional): Whether the category is active
* `show_on_sidebar` (boolean, optional): Whether to display in the sidebar navigation
* `order` (integer, optional): Sort order for display (min: 0)
* `seo_title` (string, optional): SEO meta title (max 255 characters)
* `seo_description` (string, optional): SEO meta description (max 500 characters)
* `head_html` (string, optional): Custom HTML injected into the page `` section (max 10000 characters)
**Response:**
```json theme={null}
{
"data": {
"id": 4,
"title": "DevOps & Infrastructure",
"slug": "devops",
"description": "DevOps tools, CI/CD pipelines, and cloud infrastructure",
"content": "Markdown content for the category page...",
"icon": "gear",
"custom_icon_url": "https://example.com/icons/devops.png",
"parent_id": null,
"parent_title": null,
"is_active": true,
"show_on_sidebar": true,
"order": 2,
"seo_title": "DevOps Tools & Infrastructure",
"seo_description": "Browse the best DevOps tools, CI/CD pipelines, and cloud infrastructure resources.",
"head_html": null,
"created_at": "2024-01-16T09:00:00.000000Z",
"updated_at": "2024-01-16T10:15:00.000000Z"
}
}
```
### Delete Category
Delete a category from the directory. When a parent category is deleted, its child categories will have their `parent_id` set to `null` (they become top-level categories).
```http theme={null}
DELETE /api/directories/{directory_id}/categories/{category_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `category_id` (integer, required): The ID of the category
**Response:**
```json theme={null}
{
"message": "Category deleted successfully"
}
```
## Key Features
### Hierarchical Categories
* Categories support parent-child relationships via the `parent_id` field
* You can create multi-level category trees for organizing listings
* When a parent category is deleted, child categories are automatically promoted to top-level
### Slug Generation
* Slugs are automatically generated from the category title if not provided
* Slugs must be URL-safe (lowercase letters, numbers, and hyphens only)
### Sidebar Visibility
* Use `show_on_sidebar` to control whether a category appears in the directory's sidebar navigation
* Use `order` to control the display order of categories in the sidebar
### SEO & Custom Head HTML
* Use `seo_title` and `seo_description` to set per-category meta tags for search engines
* Use `head_html` to inject custom HTML into the `` section of category pages (e.g., hreflang tags for multi-language directories)
* Use `content` to add rich markdown content displayed on the category page
### Custom Icon
* Use `custom_icon_url` to set a custom icon image URL for the category (displayed in category grids and navigation)
# Custom Fields API – Directify REST Reference
Source: https://docs.directify.app/api-integration/custom-fields
Retrieve, create, update, and delete custom fields on your directory through the Directify REST API. Full request/response schema with examples.
## Custom Fields
### Get Directory Custom Fields
Retrieve all custom fields for a specific directory.
```http theme={null}
GET /api/directories/{directory_id}/custom-fields
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"directory_id": 1,
"fieldable_type": "listing",
"name": "pricing",
"label": "Pricing",
"type": "text",
"placeholder": "Enter pricing information",
"description": "Pricing details for the tool",
"default_value": null,
"placement": "after_tags",
"placement_on_card": "before_buttons",
"is_required": false,
"is_visible": true,
"show_on_card": true,
"show_on_public_submission": false,
"show_label": false,
"show_label_on_card": true,
"show_icon": false,
"show_icon_on_card": false,
"icon": null,
"order": 1,
"options": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": 2,
"directory_id": 1,
"fieldable_type": "listing",
"name": "job_type",
"label": "Job Type",
"type": "select",
"placeholder": "Select job type",
"description": "Type of employment",
"default_value": null,
"placement": "after_tags",
"placement_on_card": "before_buttons",
"is_required": true,
"is_visible": true,
"show_on_card": true,
"show_on_public_submission": true,
"show_label": true,
"show_label_on_card": true,
"show_icon": false,
"show_icon_on_card": false,
"icon": null,
"order": 2,
"options": [
"Full-time",
"Part-time",
"Contract",
"Freelance",
"Internship"
],
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
]
}
```
### Get Single Custom Field
Retrieve a specific custom field by ID.
```http theme={null}
GET /api/directories/{directory_id}/custom-fields/{custom_field_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `custom_field_id` (integer, required): The ID of the custom field
### Create Custom Field
Create a new custom field definition in the directory.
```http theme={null}
POST /api/directories/{directory_id}/custom-fields
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"label": "Price Range",
"type": "select",
"options": ["$", "$$", "$$$"],
"fieldable_type": "listing",
"placeholder": "Select a price range",
"description": "Typical cost per person",
"default_value": null,
"value_prefix": "",
"value_suffix": "",
"is_required": false,
"is_visible": true,
"show_on_card": true,
"show_on_public_submission": true,
"filterable": true,
"order": 3
}
```
**Available fields:**
| Field | Type | Description |
| --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label` | string, required | Human-readable field label shown to users |
| `type` | string, required | Field type (see [Custom Field Types](#custom-field-types)) |
| `name` | string | Machine key used when setting values on listings. Auto-derived from `label` (lowercased, snake\_cased) if omitted — e.g. `"Price Range"` → `price_range` |
| `fieldable_type` | string | What the field attaches to: `listing` (default), `organizer`, or `article` |
| `placeholder` | string | Input placeholder text |
| `description` | string | Help text shown under the field |
| `default_value` | string | Default value |
| `value_prefix` | string | Prefix shown before the value (e.g. `$`) |
| `value_suffix` | string | Suffix shown after the value (e.g. `/mo`) |
| `options` | array | Choices for `select`, `multi_select`, and `list` types |
| `is_required` | boolean | Whether the field is required |
| `is_visible` | boolean | Whether the field shows on the listing page (default: true) |
| `show_on_card` | boolean | Show the value on listing cards |
| `show_on_public_submission` | boolean | Show the field on the public submission form |
| `show_label` | boolean | Show the label on the listing page |
| `show_label_on_card` | boolean | Show the label on cards |
| `filterable` | boolean | Allow filtering listings by this field |
| `placement` | string | Where the field renders on the listing page |
| `placement_on_card` | string | Where the value renders on the card |
| `icon` / `heroicon` | string | Field icon |
| `order` | integer | Sort order among fields |
After creating a field, set its value on a listing by passing the field's `name` as a flat key in the listing's create/update body — e.g. `{ "name": "My Tool", "price_range": "$$" }`. See [Listings → Create Listing](/api-integration/projects#create-listing).
### Update Custom Field
Update an existing custom field definition. Only include the fields you want to change.
```http theme={null}
PUT /api/directories/{directory_id}/custom-fields/{custom_field_id}
```
**Request Body:**
```json theme={null}
{
"label": "Pricing Tier",
"is_required": true,
"options": ["Free", "Pro", "Enterprise"]
}
```
### Delete Custom Field
Delete a custom field definition. This also removes the field's stored values from all listings.
```http theme={null}
DELETE /api/directories/{directory_id}/custom-fields/{custom_field_id}
```
**Response:**
```json theme={null}
{
"message": "Custom field deleted successfully"
}
```
## Custom Field Types
The API supports various custom field types:
* `text` - Simple text input
* `number` - Numeric input
* `date` - Date picker
* `file_upload` - File upload field
* `url` - URL input with validation
* `email` - Email input with validation
* `rich_editor` - Rich text editor
* `markdown` - Markdown editor
* `textarea` - Multi-line text area
* `checkbox` - Boolean toggle
* `rating` - Rating input (0-5)
* `select` - Dropdown with predefined options
* `list` - Repeatable list of values
* `multi_select` - Multiple-choice select (stored comma-separated)
* `button` - Button/CTA field
* `javascript` - Custom JavaScript
* `html` - Custom HTML
# Directories
Source: https://docs.directify.app/api-integration/directories
Manage directories through the Directify API - retrieve all directories owned by the authenticated user.
## Directories
### Get All Directories
Retrieve all directories owned by the authenticated user.
```http theme={null}
GET /api/directories
```
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"name": "Tech Startups Directory"
},
{
"id": 2,
"name": "Design Tools Directory"
}
]
}
```
# Organizers
Source: https://docs.directify.app/api-integration/organizers
Manage organizers for directories through the Directify API - create, read, update, and delete organizers with full CRUD operations.
## Organizers
Organizers represent entities such as agencies, studios, or event organizers associated with your directory. They have their own profile pages with contact information, social links, and can be linked to multiple listings. Organizers can also be assigned to submitter users, allowing them to manage their own profile from the submitter dashboard.
The organizers feature must be enabled in your directory settings before organizer pages become publicly visible. You can still manage organizers via the API regardless of this setting.
**Linking organizers to listings** is done from the listing side, not here. Pass an `organizers` array of organizer IDs when creating or updating a listing — see [Create Listing](/api-integration/projects#create-listing) and [Update Listing](/api-integration/projects#update-listing). The organizer endpoints below manage the organizer records themselves.
### Get Directory Organizers
Retrieve all organizers for a specific directory, including their associated listings.
```http theme={null}
GET /api/directories/{directory_id}/organizers
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"name": "Acme Events Co.",
"slug": "acme-events-co",
"description": "Leading event organizer in the region.",
"logo": "organizers/logos/acme-logo.png",
"logo_url": "https://yourdomain.com/storage/organizers/logos/acme-logo.png",
"cover_image": "organizers/covers/acme-cover.jpg",
"cover_image_url": "https://yourdomain.com/storage/organizers/covers/acme-cover.jpg",
"email": "hello@acme-events.com",
"phone": "+1 555-0100",
"website_url": "https://acme-events.com",
"social_links": {
"Twitter": "https://twitter.com/acmeevents",
"LinkedIn": "https://linkedin.com/company/acmeevents"
},
"user_id": 42,
"is_active": true,
"order": 0,
"projects": [
{
"id": 10,
"name": "Summer Music Festival"
}
],
"created_at": "2026-04-10T12:00:00.000000Z",
"updated_at": "2026-04-10T12:00:00.000000Z"
}
]
}
```
### Get Single Organizer
Retrieve a specific organizer by ID, including their associated listings.
```http theme={null}
GET /api/directories/{directory_id}/organizers/{organizer_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `organizer_id` (integer, required): The ID of the organizer
**Response:**
```json theme={null}
{
"data": {
"id": 1,
"name": "Acme Events Co.",
"slug": "acme-events-co",
"description": "Leading event organizer in the region.",
"logo": "organizers/logos/acme-logo.png",
"logo_url": "https://yourdomain.com/storage/organizers/logos/acme-logo.png",
"cover_image": "organizers/covers/acme-cover.jpg",
"cover_image_url": "https://yourdomain.com/storage/organizers/covers/acme-cover.jpg",
"email": "hello@acme-events.com",
"phone": "+1 555-0100",
"website_url": "https://acme-events.com",
"social_links": {
"Twitter": "https://twitter.com/acmeevents",
"LinkedIn": "https://linkedin.com/company/acmeevents"
},
"user_id": 42,
"is_active": true,
"order": 0,
"projects": [
{
"id": 10,
"name": "Summer Music Festival"
}
],
"created_at": "2026-04-10T12:00:00.000000Z",
"updated_at": "2026-04-10T12:00:00.000000Z"
}
}
```
### Create Organizer
Create a new organizer in the directory.
```http theme={null}
POST /api/directories/{directory_id}/organizers
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"name": "Bright Studios",
"description": "Creative agency specializing in digital experiences.",
"email": "info@brightstudios.com",
"phone": "+1 555-0200",
"website_url": "https://brightstudios.com",
"social_links": {
"Instagram": "https://instagram.com/brightstudios"
},
"user_id": 15,
"is_active": true
}
```
**Request Body Fields:**
* `name` (string, required): The organizer name (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from name if not provided
* `description` (string, optional): A short description (1-2 sentences) shown on cards and in the profile header
* `content` (string, optional): Long-form content (markdown supported) rendered as styled prose on the profile page
* `logo` (string, optional): Path to the logo image (max 255 characters)
* `cover_image` (string, optional): Path to the cover image (max 255 characters)
* `email` (string, optional): Contact email address
* `phone` (string, optional): Contact phone number (max 255 characters)
* `address` (string, optional): Physical address (max 255 characters)
* `website_url` (string, optional): Website URL (must be a valid URL)
* `social_links` (object, optional): Key-value pairs of platform names and URLs
* `user_id` (integer, optional): ID of a user to assign as the organizer owner. When set, this user can manage the organizer profile from the submitter dashboard
* `is_active` (boolean, optional): Whether the organizer is active (default: true)
* `order` (integer, optional): Sort order for display (default: 0)
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"name": "Bright Studios",
"slug": "bright-studios",
"description": "Creative agency specializing in digital experiences.",
"logo": null,
"logo_url": null,
"cover_image": null,
"cover_image_url": null,
"email": "info@brightstudios.com",
"phone": "+1 555-0200",
"website_url": "https://brightstudios.com",
"social_links": {
"Instagram": "https://instagram.com/brightstudios"
},
"user_id": 15,
"is_active": true,
"order": 0,
"projects": [],
"created_at": "2026-04-10T14:00:00.000000Z",
"updated_at": "2026-04-10T14:00:00.000000Z"
}
}
```
### Update Organizer
Update an existing organizer. Only include the fields you want to change.
```http theme={null}
PUT /api/directories/{directory_id}/organizers/{organizer_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `organizer_id` (integer, required): The ID of the organizer
**Request Body:**
```json theme={null}
{
"name": "Bright Studios Agency",
"email": "contact@brightstudios.com",
"social_links": {
"Instagram": "https://instagram.com/brightstudios",
"Twitter": "https://twitter.com/brightstudios"
}
}
```
**Request Body Fields:**
* `name` (string, optional): The organizer name (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only)
* `description` (string, optional): A short description (1-2 sentences) shown on cards and in the profile header
* `content` (string, optional): Long-form content (markdown supported) rendered as styled prose on the profile page
* `logo` (string, optional): Path to the logo image (max 255 characters)
* `cover_image` (string, optional): Path to the cover image (max 255 characters)
* `email` (string, optional): Contact email address
* `phone` (string, optional): Contact phone number (max 255 characters)
* `address` (string, optional): Physical address (max 255 characters)
* `website_url` (string, optional): Website URL (must be a valid URL)
* `social_links` (object, optional): Key-value pairs of platform names and URLs
* `user_id` (integer, optional): ID of a user to assign as the organizer owner
* `is_active` (boolean, optional): Whether the organizer is active
* `order` (integer, optional): Sort order for display
**Response:**
```json theme={null}
{
"data": {
"id": 2,
"name": "Bright Studios Agency",
"slug": "bright-studios",
"description": "Creative agency specializing in digital experiences.",
"logo": null,
"logo_url": null,
"cover_image": null,
"cover_image_url": null,
"email": "contact@brightstudios.com",
"phone": "+1 555-0200",
"website_url": "https://brightstudios.com",
"social_links": {
"Instagram": "https://instagram.com/brightstudios",
"Twitter": "https://twitter.com/brightstudios"
},
"user_id": 15,
"is_active": true,
"order": 0,
"projects": [],
"created_at": "2026-04-10T14:00:00.000000Z",
"updated_at": "2026-04-10T15:30:00.000000Z"
}
}
```
### Delete Organizer
Delete an organizer from the directory. This also removes all listing associations.
```http theme={null}
DELETE /api/directories/{directory_id}/organizers/{organizer_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `organizer_id` (integer, required): The ID of the organizer
**Response:**
```json theme={null}
{
"message": "Organizer deleted successfully"
}
```
## Key Features
### Slug Generation
* Slugs are automatically generated from the organizer name if not provided
* Slugs must be URL-safe (lowercase letters, numbers, and hyphens only)
### User Assignment
* Set `user_id` to assign an organizer to a submitter user
* Assigned users can edit their organizer profile from the submitter dashboard
* Users can only manage one organizer per directory
* New listings created by the assigned user are automatically linked to their organizer
### Listing Association
* Organizers have a many-to-many relationship with listings
* One organizer can be linked to multiple listings
* One listing can belong to multiple organizers
* Linking is managed through the listing form in the admin panel or via the Projects API
### Configurable Labels
* The "Organizer" label can be customized per directory in settings (e.g., "Agency", "Studio", "Vendor")
* This affects navigation labels, breadcrumbs, and public page headings
### Public Pages
* When the organizers feature is enabled, a public browse page and profile page are available
* The route prefix is configurable (default: `/organizers`, can be changed to `/agencies`, etc.)
# Custom Pages
Source: https://docs.directify.app/api-integration/pages
Manage custom pages through the Directify API - create, read, update, and delete pages with SEO support. Perfect for programmatic SEO pages like comparisons, location pages, About, Terms, and more.
## Custom Pages
In Directify, **custom pages** are standalone pages that appear in your directory's navigation (navbar, footer, sidebar) or as unlisted pages accessible via URL. They're ideal for static content like About, Terms, comparison pages, and programmatic SEO content. Pages support Markdown content and full SEO metadata.
### List Pages
Retrieve all custom pages for a directory, ordered by sort order.
```http theme={null}
GET /api/directories/{directory_id}/pages
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"title": "About Us",
"slug": "about-us",
"markdown": "# About Us\n\nWelcome to our directory...",
"placement": "navbar",
"is_markdown": true,
"is_published": true,
"is_external": false,
"external_url": null,
"new_tab": false,
"order": 0,
"seo": {
"id": 1,
"title": "About Us - My Directory",
"description": "Learn more about our directory and mission."
},
"page_url": "https://my-directory.com/pages/about-us/",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
],
"links": { ... },
"meta": { ... }
}
```
### Get Single Page
Retrieve a specific page by ID.
```http theme={null}
GET /api/directories/{directory_id}/pages/{page_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `page_id` (integer, required): The ID of the page
**Response:**
```json theme={null}
{
"data": {
"id": 1,
"title": "About Us",
"slug": "about-us",
"markdown": "# About Us\n\nWelcome to our directory...",
"placement": "navbar",
"is_markdown": true,
"is_published": true,
"is_external": false,
"external_url": null,
"new_tab": false,
"order": 0,
"seo": {
"id": 1,
"title": "About Us - My Directory",
"description": "Learn more about our directory and mission."
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com"
},
"page_url": "https://my-directory.com/pages/about-us/",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
}
```
### Create Page
Create a new custom page. Uses `updateOrCreate` based on slug to prevent duplicates.
```http theme={null}
POST /api/directories/{directory_id}/pages
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"title": "Best Pizza in NYC vs Chicago",
"slug": "pizza-nyc-vs-chicago",
"markdown": "# Best Pizza: NYC vs Chicago\n\nA detailed comparison of pizza styles...",
"placement": "unlisted",
"is_published": true,
"order": 0,
"seo": {
"title": "Best Pizza in NYC vs Chicago - Complete Comparison",
"description": "Compare NYC thin crust and Chicago deep dish pizza. Find the best pizza restaurants in both cities."
}
}
```
**Request Body Fields:**
* `title` (string, required): The page title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from title if not provided
* `markdown` (string, optional): Page content in Markdown format
* `placement` (string, optional): Where the page link appears in navigation. One of:
* `navbar` - Appears in the top navigation
* `footer` - Appears in the footer
* `sidebar` - Appears in the sidebar
* `unlisted` - Not shown in navigation, accessible only via direct URL (default)
* `is_published` (boolean, optional): Whether the page is published (default: true)
* `is_external` (boolean, optional): Whether this is a link to an external URL (default: false)
* `external_url` (string, optional): External URL if `is_external` is true (must be a valid URL)
* `new_tab` (boolean, optional): Whether external links open in a new tab (default: false)
* `order` (integer, optional): Sort order for navigation placement (default: 0)
* `seo` (object, optional): SEO metadata object:
* `title` (string, optional): SEO title (max 255 characters)
* `description` (string, optional): Meta description (max 500 characters)
**Response:**
```json theme={null}
{
"data": {
"id": 5,
"title": "Best Pizza in NYC vs Chicago",
"slug": "pizza-nyc-vs-chicago",
"markdown": "# Best Pizza: NYC vs Chicago\n\nA detailed comparison of pizza styles...",
"placement": "unlisted",
"is_markdown": true,
"is_published": true,
"is_external": false,
"external_url": null,
"new_tab": false,
"order": 0,
"seo": {
"id": 5,
"title": "Best Pizza in NYC vs Chicago - Complete Comparison",
"description": "Compare NYC thin crust and Chicago deep dish pizza. Find the best pizza restaurants in both cities."
},
"directory": {
"id": 1,
"name": "My Directory",
"slug": "my-directory",
"domain": "my-directory.com"
},
"page_url": "https://my-directory.com/pages/pizza-nyc-vs-chicago/",
"created_at": "2024-03-15T10:00:00.000000Z",
"updated_at": "2024-03-15T10:00:00.000000Z"
}
}
```
### Update Page
Update an existing page. Only pass fields you want to change. If the title changes and no slug is provided, a new slug is auto-generated.
```http theme={null}
PUT /api/directories/{directory_id}/pages/{page_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `page_id` (integer, required): The ID of the page
**Request Body:**
```json theme={null}
{
"markdown": "# Best Pizza: NYC vs Chicago\n\nUpdated comparison with new restaurants...",
"seo": {
"title": "Best Pizza in NYC vs Chicago (2024 Update)",
"description": "Updated comparison of NYC thin crust and Chicago deep dish pizza with the latest restaurant reviews."
}
}
```
**Request Body Fields:**
Same as Create Page, all fields optional.
**Response:**
Returns the updated page object (same format as Create Page response).
### Toggle Page Status
Toggle a page between published and unpublished.
```http theme={null}
PATCH /api/directories/{directory_id}/pages/{page_id}/toggle
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `page_id` (integer, required): The ID of the page
**Response:**
Returns the updated page object with toggled `is_published` status.
### Delete Page
Delete a custom page from the directory.
```http theme={null}
DELETE /api/directories/{directory_id}/pages/{page_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `page_id` (integer, required): The ID of the page
**Response:**
```json theme={null}
{
"message": "Page deleted successfully"
}
```
## Use Cases
### Programmatic SEO Pages
Create comparison pages, location pages, or "X vs Y" pages at scale using the API:
```bash theme={null}
curl -X POST https://directify.app/api/directories/1/pages \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Best Restaurants in Brooklyn vs Manhattan",
"markdown": "# Brooklyn vs Manhattan Restaurants\n\n...",
"placement": "unlisted",
"seo": {
"title": "Best Restaurants: Brooklyn vs Manhattan Compared",
"description": "Compare the best restaurants in Brooklyn and Manhattan..."
}
}'
```
### Static Content Pages
Create About, Terms, Privacy Policy, or FAQ pages that appear in your navigation:
```bash theme={null}
curl -X POST https://directify.app/api/directories/1/pages \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Terms of Service",
"markdown": "# Terms of Service\n\nLast updated: January 2024...",
"placement": "footer",
"order": 1
}'
```
### External Links in Navigation
Add external links to your directory's navigation:
```bash theme={null}
curl -X POST https://directify.app/api/directories/1/pages \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Submit a Listing",
"is_external": true,
"external_url": "https://forms.google.com/your-form",
"new_tab": true,
"placement": "navbar"
}'
```
# Listings
Source: https://docs.directify.app/api-integration/projects
Manage listings through the Directify API - create, read, update, and delete listings with full CRUD operations.
## Listings
In Directify, **listings** are the items that appear in your directory. These can be tools, services, products, or any other items you want to showcase. The API endpoints use "projects" in the URL, but they refer to listings in your directory.
### Get Directory Listings
Retrieve all listings for a specific directory with pagination.
```http theme={null}
GET /api/directories/{directory_id}/projects
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `page` (integer, optional): Page number for pagination (default: 1)
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"name": "React.js",
"slug": "react-js",
"description": "A JavaScript library for building user interfaces",
"content": "Full content body with HTML...",
"url": "https://reactjs.org",
"image_url": "https://example.com/images/react.jpg",
"logo_url": "https://example.com/logos/react.png",
"logo_alt_text": "React.js Logo",
"image_alt_text": "React.js Homepage",
"additional_image_urls": ["https://example.com/gallery1.jpg", "https://example.com/gallery2.jpg"],
"additional_images_urls": ["https://cdn.example.com/gallery1.jpg", "https://cdn.example.com/gallery2.jpg"],
"video_url": null,
"video_thumbnail_url": null,
"phone_number": "+1 (555) 123-4567",
"email": "contact@reactjs.org",
"address": "1 Hacker Way, Menlo Park, CA",
"latitude": 37.4847,
"longitude": -122.1477,
"social_links": {
"twitter": "https://twitter.com/reactjs",
"github": "https://github.com/facebook/react"
},
"categories": [
{
"id": 1,
"title": "Frontend",
"parent_title": "Web Development"
}
],
"tags": [
{
"id": 1,
"title": "Open Source",
"slug": "open-source",
"color": "#3B82F6",
"text_color": "#FFFFFF",
"is_active": true
}
],
"organizers": [
{ "id": 5, "name": "Acme Events", "slug": "acme-events" }
],
"is_active": true,
"is_featured": false,
"is_no_follow": false,
"is_claimed": false,
"votes": 42,
"seo_title": "React.js - A JavaScript Library for Building User Interfaces",
"seo_description": "React makes it painless to create interactive UIs.",
"og_image": null,
"schema": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z",
"listing_url": "https://your-directify-domain.com/app/1/projects/1/edit",
"pricing": "$0 - $100/month",
"job_type": "Full-time"
}
],
"links": {
"first": "https://your-directify-domain.com/api/directories/1/projects?page=1",
"last": "https://your-directify-domain.com/api/directories/1/projects?page=5",
"prev": null,
"next": "https://your-directify-domain.com/api/directories/1/projects?page=2"
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 5,
"per_page": 100,
"to": 100,
"total": 450
}
}
```
### Get Single Listing
Retrieve a specific listing by ID.
```http theme={null}
GET /api/directories/{directory_id}/projects/{project_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `project_id` (integer, required): The ID of the listing
**Response:**
```json theme={null}
{
"data": {
"id": 1,
"name": "React.js",
"slug": "react-js",
"description": "A JavaScript library for building user interfaces",
"content": "Full content body with HTML...",
"url": "https://reactjs.org",
"image_url": "https://example.com/images/react.jpg",
"logo_url": "https://example.com/logos/react.png",
"logo_alt_text": "React.js Logo",
"image_alt_text": "React.js Homepage",
"additional_image_urls": ["https://example.com/gallery1.jpg"],
"additional_images_urls": ["https://cdn.example.com/gallery1.jpg"],
"video_url": null,
"video_thumbnail_url": null,
"phone_number": "+1 (555) 123-4567",
"email": "contact@reactjs.org",
"address": "1 Hacker Way, Menlo Park, CA",
"latitude": 37.4847,
"longitude": -122.1477,
"social_links": {
"twitter": "https://twitter.com/reactjs",
"github": "https://github.com/facebook/react"
},
"categories": [
{
"id": 1,
"title": "Frontend",
"parent_title": "Web Development"
}
],
"tags": [
{
"id": 1,
"title": "Open Source",
"slug": "open-source",
"color": "#3B82F6",
"text_color": "#FFFFFF",
"is_active": true
}
],
"organizers": [
{ "id": 5, "name": "Acme Events", "slug": "acme-events" }
],
"is_active": true,
"is_featured": false,
"is_no_follow": false,
"is_claimed": false,
"votes": 42,
"seo_title": "React.js - A JavaScript Library for Building User Interfaces",
"seo_description": "React makes it painless to create interactive UIs.",
"og_image": null,
"schema": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z",
"listing_url": "https://your-directify-domain.com/app/1/projects/1/edit",
"pricing": "$0 - $100/month",
"job_type": "Full-time"
}
}
```
### Check Listing Exists
Check if a listing with a specific URL already exists in the directory.
```http theme={null}
POST /api/directories/{directory_id}/projects/exists
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"url": "https://example.com"
}
```
**Response (Listing exists):**
```json theme={null}
{
"message": "Listing already exists in this directory"
}
```
**Response (Listing doesn't exist):**
```json theme={null}
{
"message": "Listing does not exist in this directory"
}
```
### Create Listing
Create a new listing in the directory.
```http theme={null}
POST /api/directories/{directory_id}/projects
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"name": "Example Tool",
"url": "https://example.com",
"description": "A great tool for developers",
"content": "
Full HTML content for the listing page...
",
"phone_number": "+1 (555) 123-4567",
"email": "contact@example.com",
"address": "123 Main St, New York, NY 10001",
"latitude": 40.7128,
"longitude": -74.0060,
"social_links": {
"twitter": "https://twitter.com/example",
"linkedin": "https://linkedin.com/company/example"
},
"category_id": 1,
"categories": [1, 2],
"tags": [1, 3],
"organizers": [5, 8],
"image_url": "https://example.com/cover.jpg",
"logo_url": "https://example.com/logo.png",
"additional_image_urls": [
"https://example.com/gallery1.jpg",
"https://example.com/gallery2.jpg"
],
"seo_title": "Example Tool - Best Developer Tool",
"seo_description": "The leading tool for developers worldwide.",
"head_html": "",
"is_active": true,
"is_featured": false,
"pricing": "Free",
"job_type": "Full-time"
}
```
**Linking organizers:** Pass `organizers` as an array of organizer IDs to associate the listing with one or more [organizers](/api-integration/organizers) (agencies, studios, event hosts, etc.). Only organizers belonging to the same directory are linked — any IDs from another directory are silently ignored. Fetch available IDs with `GET /api/directories/{directory_id}/organizers`.
**Response:**
```json theme={null}
{
"data": {
"id": 123,
"name": "Example Tool",
"slug": "example-tool",
"description": "A great tool for developers",
"content": "
Full HTML content for the listing page...
",
"url": "https://example.com",
"image_url": "https://example.com/cover.jpg",
"logo_url": "https://example.com/logo.png",
"logo_alt_text": null,
"image_alt_text": null,
"additional_image_urls": ["https://example.com/gallery1.jpg", "https://example.com/gallery2.jpg"],
"additional_images_urls": ["https://example.com/gallery1.jpg", "https://example.com/gallery2.jpg"],
"video_url": null,
"video_thumbnail_url": null,
"phone_number": "+1 (555) 123-4567",
"email": "contact@example.com",
"address": "123 Main St, New York, NY 10001",
"latitude": 40.7128,
"longitude": -74.006,
"social_links": {
"twitter": "https://twitter.com/example",
"linkedin": "https://linkedin.com/company/example"
},
"categories": [
{
"id": 1,
"title": "Web Development",
"parent_title": null
},
{
"id": 2,
"title": "Frontend",
"parent_title": "Web Development"
}
],
"tags": [
{
"id": 1,
"title": "Open Source",
"slug": "open-source",
"color": "#3B82F6",
"text_color": "#FFFFFF",
"is_active": true
},
{
"id": 3,
"title": "Free Tier",
"slug": "free-tier",
"color": "#10B981",
"text_color": "#FFFFFF",
"is_active": true
}
],
"organizers": [
{ "id": 5, "name": "Acme Events", "slug": "acme-events" },
{ "id": 8, "name": "Downtown Collective", "slug": "downtown-collective" }
],
"is_active": true,
"is_featured": false,
"is_no_follow": false,
"is_claimed": false,
"votes": 0,
"seo_title": "Example Tool - Best Developer Tool",
"seo_description": "The leading tool for developers worldwide.",
"og_image": null,
"schema": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z",
"listing_url": "https://your-directify-domain.com/app/1/projects/123/edit",
"pricing": "Free",
"job_type": "Full-time"
}
}
```
### Bulk Create Listings
Create multiple listings in a single request. Up to 100 listings can be created at once. Each listing is processed independently, so if one fails, the others will still be created.
```http theme={null}
POST /api/directories/{directory_id}/projects/bulk
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"listings": [
{
"name": "Listing 1",
"description": "Description for listing 1",
"url": "https://example1.com",
"categories": [1, 2],
"tags": [1],
"organizers": [5],
"is_active": true
},
{
"name": "Listing 2",
"description": "Description for listing 2",
"category_id": 3,
"is_featured": true
},
{
"name": "Listing 3",
"description": "Description for listing 3",
"url": "https://example3.com",
"email": "contact@example3.com",
"phone_number": "+1234567890",
"address": "123 Main St"
}
]
}
```
**Available fields per listing:**
| Field | Type | Description |
| ----------------------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| `name` | string, required | The listing name |
| `slug` | string | URL slug (auto-generated from name if omitted) |
| `description` | string | Short description |
| `content` | string | Full content/body (HTML supported) |
| `url` | string | Website URL (used for duplicate detection) |
| `phone_number` | string | Phone number |
| `email` | string | Contact email |
| `address` | string | Physical address |
| `latitude` | float | Map latitude coordinate |
| `longitude` | float | Map longitude coordinate |
| `social_links` | object | Social media links (e.g., `{"twitter": "...", "linkedin": "..."}`) |
| `category_id` | integer | Single category ID |
| `categories` | array | Array of category IDs |
| `tags` | array | Array of tag IDs |
| `organizers` | array | Array of organizer IDs to link (must belong to the same directory; out-of-directory IDs are ignored) |
| `is_active` | boolean | Published status (default: true) |
| `is_featured` | boolean | Featured flag |
| `is_no_follow` | boolean | NoFollow flag |
| `logo_url` | string | Logo image URL |
| `image_url` | string | Cover image URL |
| `logo_alt_text` | string | Logo alt text |
| `image_alt_text` | string | Cover image alt text |
| `additional_image_urls` | array | Array of gallery image URLs |
| `video_url` | string | Video URL |
| `video_thumbnail_url` | string | Video thumbnail URL |
| `votes` | integer | Vote count |
| `seo_title` | string | SEO meta title |
| `seo_description` | string | SEO meta description |
| `schema` | string | JSON-LD schema markup |
| `head_html` | string | Custom HTML for the page `` section (e.g. hreflang tags) |
Custom field values can also be passed by using the custom field name as the key (e.g., `"pricing": "Free"`, `"founded_year": "2020"`).
When a `url` is provided, the API uses it for duplicate detection. If a listing with the same URL already exists in the directory, it will be returned as-is instead of creating a duplicate.
**Response (201 Created):**
```json theme={null}
{
"data": [
{
"id": 123,
"name": "Listing 1",
"slug": "listing-1",
"description": "Description for listing 1",
"url": "https://example1.com",
"is_active": true,
"is_featured": false,
"categories": [
{ "id": 1, "title": "Category A", "parent_title": null }
],
"tags": [
{ "id": 1, "title": "Tag 1", "slug": "tag-1" }
],
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": 124,
"name": "Listing 2",
"slug": "listing-2",
"description": "Description for listing 2",
"is_active": true,
"is_featured": true,
"categories": [
{ "id": 3, "title": "Category C", "parent_title": null }
],
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
],
"errors": [],
"total_created": 2,
"total_errors": 0
}
```
**Response with partial errors:**
```json theme={null}
{
"data": [
{
"id": 123,
"name": "Listing 1",
"slug": "listing-1"
}
],
"errors": [
{
"index": 1,
"name": "Listing 2",
"error": "Error description"
}
],
"total_created": 1,
"total_errors": 1
}
```
***
### Update Listing
Update an existing listing.
```http theme={null}
PUT /api/directories/{directory_id}/projects/{project_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `project_id` (integer, required): The ID of the listing
**Request Body:**
```json theme={null}
{
"name": "Updated Example Tool",
"description": "An updated description for the tool",
"phone_number": "+1 (555) 987-6543",
"email": "new@example.com",
"address": "456 Oak Ave, San Francisco, CA",
"latitude": 37.7749,
"longitude": -122.4194,
"social_links": {
"twitter": "https://twitter.com/updated",
"github": "https://github.com/updated"
},
"categories": [1],
"tags": [1],
"organizers": [5],
"seo_title": "Updated Example Tool - Now Even Better",
"seo_description": "The updated leading tool for developers.",
"is_active": true,
"is_featured": true,
"pricing": "Free - $50/month"
}
```
**Response:**
```json theme={null}
{
"data": {
"id": 123,
"name": "Updated Example Tool",
"slug": "updated-example-tool",
"description": "An updated description for the tool",
"content": null,
"url": "https://example.com",
"image_url": "https://example.com/images/updated.jpg",
"logo_url": "https://example.com/logos/updated.png",
"logo_alt_text": null,
"image_alt_text": null,
"additional_image_urls": [],
"additional_images_urls": [],
"video_url": null,
"video_thumbnail_url": null,
"phone_number": "+1 (555) 987-6543",
"email": "new@example.com",
"address": "456 Oak Ave, San Francisco, CA",
"latitude": 37.7749,
"longitude": -122.4194,
"social_links": {
"twitter": "https://twitter.com/updated",
"github": "https://github.com/updated"
},
"categories": [
{
"id": 1,
"title": "Web Development",
"parent_title": null
}
],
"tags": [
{
"id": 1,
"title": "Open Source",
"slug": "open-source",
"color": "#3B82F6",
"text_color": "#FFFFFF",
"is_active": true
}
],
"organizers": [
{ "id": 5, "name": "Acme Events", "slug": "acme-events" }
],
"is_active": true,
"is_featured": true,
"is_no_follow": false,
"is_claimed": false,
"votes": 42,
"seo_title": "Updated Example Tool - Now Even Better",
"seo_description": "The updated leading tool for developers.",
"og_image": null,
"schema": null,
"head_html": null,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T11:45:00.000000Z",
"listing_url": "https://your-directify-domain.com/app/1/projects/123/edit",
"pricing": "Free - $50/month"
}
}
```
**Partial updates:** When updating a listing, you only need to send the fields you want to change. Fields that are omitted from the request body will remain unchanged. Importantly, if you omit `categories`, `tags`, or `organizers` from a PUT request, the existing assignments will be preserved. To explicitly clear them, send empty arrays: `"categories": []`, `"tags": []`, or `"organizers": []`.
### Delete Listing
Delete a listing from the directory.
```http theme={null}
DELETE /api/directories/{directory_id}/projects/{project_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `project_id` (integer, required): The ID of the listing
**Response:**
```json theme={null}
{
"message": "Project deleted successfully"
}
```
# API SDK Examples in JavaScript, PHP, and Python
Source: https://docs.directify.app/api-integration/sdk-examples
Working code examples for integrating with the Directify API in JavaScript, PHP, and Python — authentication, requests, error handling, and common patterns.
## SDK Examples
### JavaScript/Node.js
```javascript theme={null}
const axios = require('axios');
const api = axios.create({
baseURL: 'https://directify.app/api',
headers: {
'Authorization': `Bearer ${process.env.DIRECTIFY_API_TOKEN}`,
'Content-Type': 'application/json'
}
});
// Get all directories
const directories = await api.get('/directories');
// Create a new listing
const listing = await api.post('/directories/1/projects', {
url: 'https://example.com',
name: 'My Tool',
description: 'A great tool',
categories: [1, 2],
tags: [1],
organizers: [5],
pricing: 'Free'
});
```
### PHP
```php theme={null}
use Illuminate\Support\Facades\Http;
$response = Http::withHeaders([
'Authorization' => 'Bearer ' . env('DIRECTIFY_API_TOKEN'),
'Content-Type' => 'application/json',
])
->baseUrl('https://directify.app/api')
->get('/directories');
$directories = $response->json();
// Create a listing
$listing = Http::withHeaders([
'Authorization' => 'Bearer ' . env('DIRECTIFY_API_TOKEN'),
'Content-Type' => 'application/json',
])
->baseUrl('https://directify.app/api')
->post('/directories/1/projects', [
'url' => 'https://example.com',
'name' => 'My Tool',
'description' => 'A great tool',
'categories' => [1, 2],
'tags' => [1],
'organizers' => [5],
'pricing' => 'Free'
])->json();
```
### Python
```python theme={null}
import requests
headers = {
'Authorization': f'Bearer {os.environ["DIRECTIFY_API_TOKEN"]}',
'Content-Type': 'application/json'
}
base_url = 'https://directify.app/api'
# Get all directories
response = requests.get(f'{base_url}/directories', headers=headers)
directories = response.json()
# Create a listing
listing_data = {
'url': 'https://example.com',
'name': 'My Tool',
'description': 'A great tool',
'categories': [1, 2],
'tags': [1],
'organizers': [5],
'pricing': 'Free'
}
response = requests.post(
f'{base_url}/directories/1/projects',
headers=headers,
json=listing_data
)
listing = response.json()
```
# Tags
Source: https://docs.directify.app/api-integration/tags
Manage tags for directories through the Directify API - create, read, update, and delete tags with full CRUD operations.
## Tags
Tags provide a flexible labeling system for your directory listings. Unlike categories which are hierarchical, tags are flat labels that can be applied to listings for filtering and visual identification. Tags support custom colors and icons for enhanced display.
### Get Directory Tags
Retrieve all active tags for a specific directory.
```http theme={null}
GET /api/directories/{directory_id}/tags
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Response:**
```json theme={null}
{
"data": [
{
"id": 1,
"title": "Open Source",
"slug": "open-source",
"is_active": true,
"icon": null,
"heroicon": "code-bracket",
"text_color": "#FFFFFF",
"show_title": true,
"show_icon": true,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
},
{
"id": 2,
"title": "Free Tier",
"slug": "free-tier",
"is_active": true,
"icon": null,
"heroicon": "currency-dollar",
"text_color": "#10B981",
"show_title": true,
"show_icon": true,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
]
}
```
### Get Single Tag
Retrieve a specific tag by ID.
```http theme={null}
GET /api/directories/{directory_id}/tags/{tag_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `tag_id` (integer, required): The ID of the tag
**Response:**
```json theme={null}
{
"data": {
"id": 1,
"title": "Open Source",
"slug": "open-source",
"is_active": true,
"icon": null,
"heroicon": "code-bracket",
"text_color": "#FFFFFF",
"show_title": true,
"show_icon": true,
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:30:00.000000Z"
}
}
```
### Create Tag
Create a new tag in the directory.
```http theme={null}
POST /api/directories/{directory_id}/tags
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
**Request Body:**
```json theme={null}
{
"title": "New Release",
"slug": "new-release",
"is_active": true,
"heroicon": "sparkles",
"text_color": "#F59E0B",
"show_title": true,
"show_icon": true
}
```
**Request Body Fields:**
* `title` (string, required): The tag title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only). Auto-generated from title if not provided
* `is_active` (boolean, optional): Whether the tag is active (default: true)
* `icon` (string, optional): Custom uploaded icon path (max 255 characters)
* `heroicon` (string, optional): Heroicon name to use as the tag icon (max 255 characters). Takes priority over `icon` when both are set
* `text_color` (string, optional): Text/accent color for the tag display (max 255 characters, e.g. "#FF0000")
* `show_title` (boolean, optional): Whether to display the tag title (default: true)
* `show_icon` (boolean, optional): Whether to display the tag icon (default: true)
**Response:**
```json theme={null}
{
"data": {
"id": 3,
"title": "New Release",
"slug": "new-release",
"is_active": true,
"icon": null,
"heroicon": "sparkles",
"text_color": "#F59E0B",
"show_title": true,
"show_icon": true,
"created_at": "2024-01-16T09:00:00.000000Z",
"updated_at": "2024-01-16T09:00:00.000000Z"
}
}
```
### Update Tag
Update an existing tag.
```http theme={null}
PUT /api/directories/{directory_id}/tags/{tag_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `tag_id` (integer, required): The ID of the tag
**Request Body:**
```json theme={null}
{
"title": "Recently Updated",
"text_color": "#3B82F6",
"heroicon": "arrow-path"
}
```
**Request Body Fields:**
* `title` (string, optional): The tag title (max 255 characters)
* `slug` (string, optional): URL-safe slug (lowercase letters, numbers, hyphens only)
* `is_active` (boolean, optional): Whether the tag is active
* `icon` (string, optional): Custom uploaded icon path (max 255 characters)
* `heroicon` (string, optional): Heroicon name to use as the tag icon (max 255 characters)
* `text_color` (string, optional): Text/accent color for the tag display (max 255 characters)
* `show_title` (boolean, optional): Whether to display the tag title
* `show_icon` (boolean, optional): Whether to display the tag icon
**Response:**
```json theme={null}
{
"data": {
"id": 3,
"title": "Recently Updated",
"slug": "new-release",
"is_active": true,
"icon": null,
"heroicon": "arrow-path",
"text_color": "#3B82F6",
"show_title": true,
"show_icon": true,
"created_at": "2024-01-16T09:00:00.000000Z",
"updated_at": "2024-01-16T10:15:00.000000Z"
}
}
```
### Delete Tag
Delete a tag from the directory.
```http theme={null}
DELETE /api/directories/{directory_id}/tags/{tag_id}
```
**Parameters:**
* `directory_id` (integer, required): The ID of the directory
* `tag_id` (integer, required): The ID of the tag
**Response:**
```json theme={null}
{
"message": "Tag deleted successfully"
}
```
## Key Features
### Slug Generation
* Slugs are automatically generated from the tag title if not provided
* Slugs must be URL-safe (lowercase letters, numbers, and hyphens only)
### Icon Support
* Tags support two types of icons: custom uploaded icons (`icon`) and Heroicons (`heroicon`)
* When both are set, `heroicon` takes priority for display
* Use `show_icon` to control icon visibility
### Display Customization
* `text_color` sets the accent color for the tag (useful for color-coded labels)
* `show_title` and `show_icon` control which parts of the tag are visible
* Combine these options to create icon-only tags, text-only tags, or full tags with both
# Add Article to your directory
Source: https://docs.directify.app/blog/add-article
Comprehensive guide on creating and managing blog articles for directory websites. Learn about content formatting options, scheduling posts, media management, and SEO best practices for optimal article performance.
Articles allow you to create blog content for your directory website. Here's a breakdown of the available fields and settings when creating or editing an article:
### Basic Information
* **Title** (Required) - The title of your article
* **Slug** - URL-friendly version of the title
* Auto-generated from title if left blank
* Can be customized for SEO purposes
### Content Options
* **Content Format** - Choose between:
* Rich Text Editor - Visual WYSIWYG editor
* Markdown - Write in markdown format
* Supports standard markdown syntax
* Embed videos using:
```md theme={null}
::: @iframe https://www.youtube.com/embed/VIDEO_ID :::
```
### Publishing Settings
* **Published** - Toggle article visibility
* When enabled, article is live on your site
* When disabled, article is hidden from public view
* **Published At** - Schedule publication date/time
* Set future date to schedule posts
* Defaults to current time in UTC
### Media
* **Thumbnail** - Featured image for the article
* Upload image directly
* Supports image editing with preset aspect ratios:
* 16:9 (Widescreen)
* 4:3 (Standard)
* 1:1 (Square)
* **Thumbnail URL** - Alternative to uploaded thumbnail
* Use external image URL
* Only used if no thumbnail is uploaded
## Best Practices
1. Use clear, descriptive titles
2. Add engaging thumbnails
3. Format content for readability
4. Schedule posts strategically
5. Preview before publishing
Rich media like images and videos help make your articles more engaging. Use the built-in file upload capabilities to easily add media to your content.
# Import and Export Blog Articles
Source: https://docs.directify.app/blog/import-export
Complete guide to importing and exporting blog articles in your directory website. Learn how to bulk import articles from CSV, migrate from WordPress, and export existing content with detailed error handling and results tracking.
Directify provides powerful import and export capabilities to help you manage your blog articles in bulk. You can easily import articles from a CSV file, including WordPress exports, and export your existing articles to CSV format.
## Importing Articles
To import articles into your directory:
1. Download the example CSV file to see the correct format
2. Prepare your CSV file with the following columns:
### Required Fields
* **title** - The article title (required, max 255 characters)
* **content** - The main content of your article
### Optional Fields
* **slug** - URL-friendly version of the title (max 255 characters, auto-generated if left blank)
* **published** - Whether the article should be published (true/false)
* **published\_at** - Publication date and time in UTC format
* **thumbnail\_url** - URL to the article's featured image
* **meta\_title** - Custom SEO title
* **meta\_description** - Custom SEO description
### WordPress Migration
You can easily migrate your existing WordPress blog by:
1. Exporting your WordPress articles to XML
2. Using our WordPress converter tool to transform the XML to CSV
3. Importing the resulting CSV file
### Import Settings
When importing articles, you can configure:
1. **Update Existing** - Choose whether to update existing articles
2. **Default Publishing** - Set whether imported articles should be published by default
3. **Preserve Dates** - Keep original publication dates from the import file
Make sure your CSV file uses UTF-8 encoding for proper handling of special characters and formatting.
### Import Results
After the import completes, you'll see a notification in the top-right corner with:
* Number of successfully imported articles
* Number of failed imports
* Option to download detailed results
The results file includes all attempted imports with status and error messages. To review failures:
1. Download the results CSV
2. Scroll right to see the "Error" column
3. Review specific error messages for each failed row
Common error messages include:
* Invalid title length
* Missing required fields
* Malformed dates
* Invalid URLs
Use the error messages to correct issues in your import file, then retry importing the failed rows.
## Exporting Articles
You can export all your articles to CSV format for backup or bulk editing purposes. The exported file will contain all the fields listed above.
Large blogs with many articles may take a few moments to export. The system will notify you once your export is ready for download.
# Add categories to your directory website
Source: https://docs.directify.app/categories/add-category
Learn how to organize your directory with categories, including creating hierarchical structures, adding icons, and managing visibility settings for optimal navigation
Categories help organize your listings and make them easier to discover. Here's a breakdown of all the available fields when creating or editing a category:
### Required Fields
* **Title** (Required) - The name of your category that will be displayed throughout the directory
### Organization
* **Parent Category** - Make this a sub-category by selecting a parent category
* **Icon** - Choose an icon to visually represent this category
* Select from hundreds of built-in icons
* Icons appear in the sidebar and category cards
### Content
* **Content** (Optional) - Add rich markdown content to describe the category
* Write formatted text with markdown
* Add images and media
* Embed videos from YouTube/Vimeo using:
```md theme={null}
::: @iframe https://www.youtube.com/embed/VIDEO_ID :::
```
### Visibility Settings
* **Show on Sidebar** - Control category visibility in the navigation sidebar
* When disabled, the category won't appear in the sidebar menu
* Listings in hidden categories remain accessible through search and direct links
* **Active** - Toggle the overall visibility of the category
* Inactive categories are completely hidden from the directory
* Use this to temporarily hide categories without deleting them
## Best Practices
1. Use clear, descriptive category names
2. Create a logical hierarchy with parent/sub categories
3. Add icons to make categories visually distinct
4. Use content area to explain category purpose
5. Keep your category structure simple and intuitive
While you can create unlimited categories, we recommend keeping the structure simple to help visitors easily find what they're looking for.
***
Learn about importing listings
Learn about ScreenshotOne integration
Learn about SEO
Learn about Custom Fields
# Import and Export Directory Categories
Source: https://docs.directify.app/categories/import-export
Bulk import and export categories for your Directify directory using CSV — the fast way to manage large category lists without manual entry.
Directify provides powerful import and export capabilities to help you manage your listings in bulk. You can easily import listings from a CSV file and export your existing listings to CSV format.
## Importing Categories
To import categories into your directory:
1. Download the example CSV file to see the correct format
2. Prepare your CSV file with the following columns:
### Required Fields
* **title** - The category name (required, max 255 characters)
### Optional Fields
* **slug** - URL-friendly version of the title (max 255 characters, auto-generated if left blank)
* **content** - Detailed content/description for the category
### Import Settings
When importing categories, you can configure:
1. **Update Existing** - Choose whether to update existing categories
2. **Default Publishing** - Set whether imported categories should be published by default
Make sure your CSV file uses UTF-8 encoding for proper handling of special characters.
### Import Results
After the import completes, you'll see a notification in the top-right corner with:
* Number of successfully imported articles
* Number of failed imports
* Option to download detailed results
The results file includes all attempted imports with status and error messages. To review failures:
1. Download the results CSV
2. Scroll right to see the "Error" column
3. Review specific error messages for each failed row
Common error messages include:
* Invalid title length
* Missing required fields
* Malformed dates
* Invalid URLs
Use the error messages to correct issues in your import file, then retry importing the failed rows.
## Exporting Categories
You can export all your categories to CSV format for backup or bulk editing purposes. The exported file will contain all the fields listed above.
Large directories with many categories may take a few moments to export. The system will notify you once your export is ready for download.
# Enhanced Markdown Content Syntax
Source: https://docs.directify.app/content/markdown-syntax
Master Directifys enhanced markdown syntax with custom components for iframes, FAQs, CTAs, and multimedia content integration
Directify supports enhanced markdown syntax that goes beyond standard markdown capabilities. Use powerful custom components to create rich, interactive content with embedded videos, structured FAQs, call-to-action sections, and more.
## Standard Markdown Support
Directify fully supports all standard markdown syntax including:
### Text Formatting
* **Bold text** with `**bold**` or `__bold__`
* *Italic text* with `*italic*` or `_italic_`
* `Inline code` with backticks
* ~~Strikethrough~~ with `~~text~~`
### Headers
```markdown theme={null}
# H1 Header
## H2 Header
### H3 Header
#### H4 Header
##### H5 Header
###### H6 Header
```
### Lists
```markdown theme={null}
- Unordered list item
- Another item
- Nested item
1. Ordered list item
2. Second item
1. Nested ordered item
```
### Links and Images
```markdown theme={null}
[Link text](https://example.com)

```
### Code Blocks
````markdown theme={null}
```javascript
function example() {
console.log("Hello World!");
}
```
````
## Enhanced Syntax with ::: Components
Directify extends markdown with custom components using the `::: @component :::` syntax. These components provide rich functionality beyond standard markdown.
## Video and Media Embedding
### @iframe Component
Embed any iframe content including YouTube, Vimeo, and other multimedia:
#### Syntax
```markdown theme={null}
::: @iframe https://www.youtube.com/embed/BHshHvKmJYQ?si=MuJt--gDt3HjuHRC :::
```
#### Supported Platforms
* **YouTube**: Use embed URLs from YouTube
* **Vimeo**: Direct embed URLs
* **Google Maps**: Embed map iframes
* **CodePen**: Interactive code demonstrations
* **Slides**: Google Slides, SlideShare presentations
* **Forms**: External form embeds
* **Any iframe content**: Custom widgets, tools, etc.
#### Examples
**YouTube Video:**
```markdown theme={null}
::: @iframe https://www.youtube.com/embed/dQw4w9WgXcQ :::
```
**Vimeo Video:**
```markdown theme={null}
::: @iframe https://player.vimeo.com/video/123456789 :::
```
**Google Maps:**
```markdown theme={null}
::: @iframe https://www.google.com/maps/embed?pb=!1m18!1m12... :::
```
#### Technical Details
* **Responsive**: Automatically sized to full width (`w-full h-96`)
* **Secure**: Includes proper security attributes
* **Optimized**: Includes performance optimizations for media playback
* **Accessible**: Proper iframe labeling and keyboard navigation
Always use embed URLs from trusted sources. Avoid direct links to video files - use platform-specific embed URLs instead.
## FAQ Components
Create structured FAQ sections with automatic schema markup for SEO benefits:
### Basic FAQ Syntax
```markdown theme={null}
::: faq
### What's the best way to use schema markup?
Schema markup is a game-changer for SEO. It helps search engines understand your content better and can lead to rich snippets in search results. The key is to use structured data that matches your content type.
:::
::: faq
### How do I optimize for featured snippets?
Focus on answering specific questions clearly and concisely. Use header tags (H2, H3) for questions and provide direct, comprehensive answers. Structure your content in lists, tables, or step-by-step formats when appropriate.
:::
```
### Multiple FAQ Sections
```markdown theme={null}
::: faq
### General Questions
Simply create an account and follow the onboarding process. Our wizard will guide you through the essential setup steps.
::: faq
### Is there a free trial?
Yes! We offer a 14-day free trial with access to all features. No credit card required.
:::
::: faq
### Technical Questions
We support JavaScript, Python, PHP, Ruby, and more. Check our documentation for the complete list.
:::
::: faq
### Can I integrate with my existing tools?
Absolutely! We provide APIs and webhooks for seamless integration with popular development tools.
:::
```
### FAQ Features
* **Automatic Schema**: SEO-optimized FAQ schema markup
* **Collapsible Design**: User-friendly accordion interface
* **Search Friendly**: Properly structured for search engines
* **Mobile Optimized**: Responsive design for all devices
## Call-to-Action (CTA) Components
Add compelling call-to-action sections to drive user engagement:
## Best Practices for Enhanced Markdown
### Content Structure
1. **Use Headers Hierarchically** - Maintain proper H1, H2, H3 structure
2. **Break Up Text** - Use components to create visual breaks
3. **Balance Content** - Mix text with multimedia for engagement
4. **Mobile-First** - Consider how content appears on mobile devices
### SEO Optimization
1. **FAQ Schema** - Use FAQ components for common questions
2. **Descriptive Alt Text** - Always include alt text for images
3. **Internal Linking** - Link to related content within your directory
4. **Header Optimization** - Use descriptive, keyword-rich headers
### User Experience
1. **Progressive Disclosure** - Use FAQs to reveal information gradually
2. **Visual Breaks** - Embed videos and media to break up text
3. **Clear CTAs** - Strategic placement of call-to-action components
4. **Readable Formatting** - Proper use of lists, headers, and emphasis
## Component Combinations
### Rich Content Example
```markdown theme={null}
# Complete Guide to Directory Marketing
Marketing your directory effectively requires a multi-channel approach. Let's explore the key strategies.
## Video Overview
::: @iframe https://www.youtube.com/embed/marketing-guide-123 :::
## Common Questions
::: faq
### How long does it take to see results?
Most directories see initial traffic within 2-4 weeks of implementing these strategies. Significant growth typically occurs within 3-6 months with consistent effort.
### What's the most effective marketing channel?
It depends on your niche, but content marketing combined with SEO tends to provide the best long-term ROI for directory websites.
:::
Ready to implement these strategies?
## Advanced Techniques
For more advanced marketing techniques, check out our comprehensive guide...
```
## Technical Implementation
### Where Components Work
Enhanced markdown syntax is available in:
* **Listing Content** - Rich descriptions with multimedia
* **Article Content** - Blog posts with embedded media
* **Category Descriptions** - Detailed category explanations
* **Custom Pages** - Landing pages and informational content
* **Directory Descriptions** - About pages and site descriptions
* **Ad Content** - Rich advertising content
### Processing Order
1. **Standard Markdown** - Converted to HTML first
2. **@iframe Components** - Processed and embedded
3. **FAQ Components** - Structured with schema markup
4. **CTA Components** - Rendered with directory styling
5. **Cleanup** - Remaining syntax markers removed
### Performance Considerations
* **Lazy Loading** - Iframes load efficiently
* **Schema Caching** - FAQ schemas cached for performance
* **Mobile Optimization** - All components responsive
* **SEO Benefits** - Enhanced search engine visibility
## Troubleshooting Common Issues
### Iframe Not Loading
* **Check URL**: Ensure you're using embed URLs, not direct links
* **HTTPS Required**: Some platforms require secure connections
* **Platform Restrictions**: Some sites block iframe embedding
### FAQ Not Displaying
* **Header Format**: Ensure questions use `###` (H3) headers
* **Content Structure**: Place content directly after question headers
* **Proper Syntax**: Check opening and closing `:::` markers
### Syntax Not Processing
* **Exact Format**: Use exact `::: component :::` syntax
* **No Extra Spaces**: Avoid extra spaces in component declarations
* **Case Sensitive**: Component names are case-sensitive
## Migration from Standard Markdown
If you have existing markdown content:
1. **Backup Content** - Save original markdown files
2. **Gradual Enhancement** - Add components incrementally
3. **Test Thoroughly** - Preview content before publishing
4. **Update Links** - Ensure all embedded content works
5. **Monitor Performance** - Check loading speeds after updates
Start with one component type (like @iframe) and gradually incorporate others as you become comfortable with the enhanced syntax.
## Advanced Examples
### Product Showcase
```markdown theme={null}
# Featured Directory Tool
Meet our latest integration - a powerful tool for directory owners.
::: @iframe https://www.youtube.com/embed/product-demo-456 :::
## Common Questions
::: faq
### How does the integration work?
The integration connects directly with your existing directory database, automatically syncing listings and user data in real-time.
### Is technical knowledge required?
No technical knowledge is needed. Our one-click setup process handles all the complex configuration automatically.
:::
```
### Educational Content
```markdown theme={null}
# SEO Guide for Directories
## Video Tutorial
::: @iframe https://www.youtube.com/embed/seo-tutorial-789 :::
## Interactive Example
::: @iframe https://codepen.io/example/seo-demo :::
## Frequently Asked Questions
::: faq
### How often should I update my directory content?
Regular updates are crucial for SEO. Aim for new listings weekly and refresh existing content monthly.
### What's the ideal directory structure?
A clear hierarchical structure with logical categories and subcategories works best for both users and search engines.
:::
```
Your enhanced markdown content is now ready to engage users with rich, interactive experiences while maintaining excellent SEO performance!
***
Learn how to create rich listing content
Build engaging custom pages with enhanced markdown
# Create Custom Links for Your Directory Website
Source: https://docs.directify.app/custom-pages/links
Learn how to create custom links for your directory website, such as "About Us", "Contact", or any informational pages
Custom links allow you to add external links to your directory website's navigation. These links can point to any URL and be placed in either the header or sidebar navigation.
## Creating a Custom Link
To create a custom link:
1. Enter a title for your link - This will appear in the navigation
2. Add the URL - The external URL this link should point to
3. Choose the placement (Header or Sidebar)
# Create Custom Pages for Your Directory Website
Source: https://docs.directify.app/custom-pages/pages
Learn how to create SEO-optimized custom pages like About Us and Contact pages with markdown or drag-and-drop builder to enhance your business directory website
Custom pages allow you to create additional content pages for your directory website, such as "About Us", "Contact", or any informational pages. These pages can be placed in either the header or sidebar navigation.
## Creating a Custom Page
To create a custom page:
1. Enter a title for your page
2. Choose the placement (Header or Sidebar)
3. Select your content type:
* **Markdown** - Write content using markdown formatting
* **Page Builder** - Use a visual drag-and-drop builder
### Page Settings
* **Published** - Controls whether the page is visible on your site
* **Content Type** - Choose between Markdown or Page Builder
* **Placement** - Select where the page appears in navigation
### Markdown Content
When using markdown, you can:
* Format text with headers, lists, bold, italics etc.
* Add images and media
* Embed videos from YouTube, Vimeo and other platforms
* Include file attachments
### Page Builder
The page builder provides drag-and-drop blocks for:
* **Headings** - H1-H6 text headers
* **Paragraphs** - Rich text content with formatting
* **Images** - Upload and embed images with alt text
* **Projects** - Display selected projects from your directory
Images uploaded through either method are automatically optimized and stored securely.
## Managing Pages
From the pages list view you can:
* Edit existing pages
* Change page visibility
* Reorder pages within their placement section
* Delete unused pages
Use custom pages strategically to provide valuable information to your directory visitors while keeping navigation clean and organized.
# Create your first no-code directory website with Directify
Source: https://docs.directify.app/directories/create-directory
Step-by-step guide to creating your first directory website with Directify. Learn how to set up your directory name, title, and description, with options for SEO optimization and future customization.
Unlike other No-Code tools, to create a directory with
Directify you don't need to create all the sections yourself,
do drag & drop blocks, etc.
Creating a directory with Directify is simple and straightforward. Just follow these steps:
1. Enter your directory name - This will appear in the header
2. Add a title - This helps describe what your directory is about
3. Write a description - Give visitors more context about your directory
That's all you need to get started! While there are many other customization options available, they're completely optional and can be configured later.
Once your directory is created, you'll have access to the full suite of customization options to make it truly your own.
## Columns explained
### Name
Your directory name appears next to your logo in the header. It helps visitors recognize your brand right away. You can change it anytime in settings or hide it completely - it's up to you!
### Title
The title of the directory is displayed prominently in the header and serves as the main H1 heading for SEO purposes. It helps visitors and search engines understand what your directory is about. Like other elements, you can choose to hide it if it doesn't fit your design preferences.
The title also will be used as the SEO title (meta title) for your website.
You can overwrite SEO metadata if you want to make them more specific.
### Description
The description appears below the title in the header section and helps provide additional context about your directory. Like the title, it serves dual purposes - it's visible to visitors and also used as the meta description for SEO. You can customize or hide the description through the settings panel.
***
Configure your directory subdomain
Connect your own domain name
# Connect a Custom Domain to Your Directory
Source: https://docs.directify.app/directories/custom-domain
Connect your own domain to your Directify directory and serve it over HTTPS with an auto-managed SSL certificate — fully branded, zero setup.
Custom domains allow you to use your own domain (e.g., `yourdomain.com`) instead of the default Directify subdomain. Your directory will be served over HTTPS with an automatically managed SSL certificate.
## Step 1: Add Your Domain
1. Go to your **Directory Settings**
2. Click **Custom Domain** in the sidebar
3. Enter your domain name (e.g., `yourdomain.com` or `www.yourdomain.com`)
4. Click **Next**
## Step 2: Choose Setup Method
After entering your domain, you'll see two options for connecting your domain. Choose the method that works best for you.
### Change Nameservers
The easiest and recommended method. Point your domain's nameservers to Directify, and we'll handle all DNS configuration automatically.
**Update your nameservers at your domain registrar to:**
| Nameserver |
| ------------------- |
| `ns1.directify.app` |
| `ns2.directify.app` |
**Why this is recommended:**
* Simplest setup - just change nameservers once
* We manage all DNS records for you automatically
* Automatic configuration for both `www` and non-`www` versions
* No CNAME flattening issues with root domains
**Managing DNS Records:** After switching to Directify nameservers, you can manage your DNS records directly from your directory settings. Go to **Settings** → **Manage DNS Records** to add, edit, or delete records like MX (email), TXT (SPF, DKIM), and more.
### Add CNAME Records
If you prefer to keep your current DNS provider (e.g., you have email or other DNS records to manage), add CNAME records manually.
**For root/apex domains (e.g., `yourdomain.com`)**, you need to add **both** records:
| Type | Name | Target |
| ----- | ----------------------- | ---------------------- |
| CNAME | `@` or `yourdomain.com` | `custom.directify.app` |
| CNAME | `www` | `custom.directify.app` |
**For subdomains (e.g., `directory.yourdomain.com`)**, add only one record:
| Type | Name | Target |
| ----- | ----------- | ---------------------- |
| CNAME | `directory` | `custom.directify.app` |
**For root domains:** Some DNS providers don't support CNAME records on the root domain (`@`). In this case, we recommend using **Option 1 (Nameservers)** instead, or see [Root Domain Limitations](#root-domain-apex-cname-limitations) for other workarounds.
We automatically handle redirects between `www` and non-`www` versions of your domain. That's why both CNAME records are required for apex domains.
## Step 3: Wait for Verification
After configuring your DNS (either nameservers or CNAME records), click **Submit** to start the verification process.
DNS propagation typically takes:
* **1-5 minutes** - Cloudflare, AWS Route 53
* **1-4 hours** - Google Domains, Namecheap
* **24-48 hours** - Nameserver changes at some registrars
You'll receive an email notification when your domain is verified and active.
## Step 4: SSL Certificate
Once DNS is verified, Directify automatically provisions a free SSL certificate. No action required - HTTPS is enabled automatically.
Your directory will be accessible at `https://yourdomain.com` within minutes of DNS verification.
***
## DNS Provider Examples
### Changing Nameservers
1. Go to **Domain List** → click **Manage** next to your domain
2. Find the **Nameservers** section
3. Select **Custom DNS**
4. Enter:
* `ns1.directify.app`
* `ns2.directify.app`
5. Click the green checkmark to save
1. Go to **My Products** → **Domains**
2. Click on your domain → **DNS** → **Nameservers**
3. Click **Change Nameservers** → **Enter my own nameservers**
4. Enter:
* `ns1.directify.app`
* `ns2.directify.app`
5. Click **Save**
1. Go to **DNS** in the left sidebar
2. Click **Custom name servers**
3. Enter:
* `ns1.directify.app`
* `ns2.directify.app`
4. Click **Save**
1. Go to **Domain Management**
2. Click the dropdown next to your domain → **Edit**
3. Scroll to **Authoritative Nameservers**
4. Enter:
* `ns1.directify.app`
* `ns2.directify.app`
5. Click **Submit**
### Adding CNAME Records
1. Go to your domain's DNS settings
2. Click **Add record**
3. Add the first CNAME record:
* Type: `CNAME`
* Name: `@`
* Target: `custom.directify.app`
* Proxy status: DNS only (gray cloud) or Proxied (orange cloud)
4. Add the second CNAME record:
* Type: `CNAME`
* Name: `www`
* Target: `custom.directify.app`
1. Go to **Domain List** → **Manage** → **Advanced DNS**
2. Click **Add New Record**
3. Add the first CNAME record:
* Type: `CNAME`
* Host: `@`
* Target: `custom.directify.app`
* TTL: Automatic
4. Add the second CNAME record:
* Type: `CNAME`
* Host: `www`
* Target: `custom.directify.app`
Namecheap may not support CNAME on root domain. Use the **Nameservers** method instead, or see workarounds below.
1. Go to **My Products** → **DNS**
2. Click **Add** in the Records section
3. Add the first CNAME record:
* Type: `CNAME`
* Name: `@`
* Value: `custom.directify.app`
* TTL: Default
4. Add the second CNAME record:
* Type: `CNAME`
* Name: `www`
* Value: `custom.directify.app`
GoDaddy may not support CNAME on root domain. Use the **Nameservers** method instead, or see workarounds below.
1. Go to **DNS** in the left sidebar
2. Scroll to **Custom records**
3. Click **Manage custom records**
4. Add both CNAME records as shown in your setup wizard
***
## Troubleshooting
* **Verify DNS records are correct** - Double-check all record types, names, and values
* **Clear local DNS cache** - Run `ipconfig /flushdns` (Windows) or `sudo dscacheutil -flushcache` (Mac)
* **Check propagation status** - Use [whatsmydns.net](https://whatsmydns.net) to verify your records are visible globally
* **Wait longer** - Nameserver changes can take up to 48 hours to propagate
* **Wait up to 1 hour** after DNS verification for SSL to fully activate
* **Verify DNS is correct** - SSL requires your domain to point to `custom.directify.app` (CNAME) or use Directify nameservers
* Verify your DNS settings (nameservers or CNAME records)
* Check for typos in record values
* If using CNAME, ensure **both** root and www records are added
* Ensure you're editing DNS for the correct domain
* Contact support on [Discord](https://discord.gg/B9hTD4kAJY) if issues persist after 24 hours
This domain is already connected to another Directify directory. If you own this domain and need to transfer it, contact support.
Many DNS providers don't support CNAME on root domains. **The easiest solution is to use the Nameservers method** (Option 1). See [Root Domain Limitations](#root-domain-apex-cname-limitations) for more details.
***
## Removing a Custom Domain
1. Go to **Directory Settings** → **Custom Domain**
2. Click **Remove Domain**
3. Confirm the removal
Your directory will revert to using the default Directify subdomain. You can optionally revert your nameservers or remove the DNS records from your domain registrar.
***
## Advanced Configuration
### WWW and Non-WWW Handling
Directify automatically handles both `www.yourdomain.com` and `yourdomain.com`. No matter which version a visitor uses, they'll reach your directory. We recommend:
* **Using Nameservers (Option 1):** Both versions work automatically
* **Using CNAME (Option 2):** Add both the root and `www` CNAME records
### Multiple domains
Currently, each directory supports one custom domain. If you need multiple domains pointing to the same directory, set up redirects at the DNS level to your primary custom domain.
***
## Root Domain (Apex) CNAME Limitations
Some DNS providers don't support CNAME records on root/apex domains (e.g., `yourdomain.com` without any subdomain). This is a technical limitation of the DNS specification, not a Directify limitation.
**Recommended Solution:** Use the **Nameservers method** (Option 1) to avoid this issue entirely. Point your nameservers to `ns1.directify.app` and `ns2.directify.app`, and we handle everything automatically.
### How to check if your provider supports it
Try adding a CNAME record with `@` as the name. If your provider shows an error like "CNAME not allowed on root domain" or "Cannot add CNAME to apex", you'll need to use one of the workarounds below.
### Providers that support root domain CNAME
These providers support CNAME flattening, ANAME, or ALIAS records on root domains:
* **Cloudflare** (free) - Automatic CNAME flattening
* **AWS Route 53** - ALIAS records
* **DNSimple** - ALIAS records
* **DNS Made Easy** - ANAME records
* **NS1** - ALIAS records
* **Netlify DNS** - Automatic handling
* **Vercel DNS** - Automatic handling
### Providers that don't support root domain CNAME
* GoDaddy (basic DNS)
* Namecheap (basic DNS)
* Some traditional registrar DNS services
### Workarounds
The simplest solution. Change your nameservers to Directify's:
| Nameserver |
| ------------------- |
| `ns1.directify.app` |
| `ns2.directify.app` |
We'll handle all DNS configuration automatically, including the root domain issue.
Instead of `yourdomain.com`, use `www.yourdomain.com`:
1. Set up `www.yourdomain.com` as your custom domain in Directify
2. Set up a redirect from your root domain to the www subdomain
**Using your registrar's forwarding feature:**
Most registrars offer URL forwarding. Set up a redirect from `yourdomain.com` to `www.yourdomain.com`.
Cloudflare offers free DNS hosting with automatic CNAME flattening:
1. Create a free account at [cloudflare.com](https://cloudflare.com)
2. Add your domain to Cloudflare
3. Update your domain's nameservers to Cloudflare's (provided during setup)
4. Add your CNAME records in Cloudflare's dashboard
You don't need to transfer your domain - just point the nameservers to Cloudflare. Your domain registration stays with your current registrar.
Some providers offer ALIAS or ANAME records as alternatives to CNAME for root domains. Check your DNS provider's documentation for:
* "ALIAS record"
* "ANAME record"
* "Flattened CNAME"
* "Virtual CNAME"
If available, use the same target (`custom.directify.app`) with an ALIAS/ANAME record type.
***
## Need Help?
Join our Discord for quick support
Email us at [sergey@directify.app](mailto:sergey@directify.app)
***
Learn about free subdomain configuration
Customize your directory design and branding
# Customize Your Directory: Logo, Themes, Templates
Source: https://docs.directify.app/directories/customize-your-directory
Customize your Directify directory with logos, themes, templates, fonts, colors, and custom styling — make your directory match your brand.
## Logo & Favicon
Upload your logo and favicon in the settings. Supported formats: PNG, JPG, SVG, ICO.
## Templates
Choose from [8 templates](https://directify.app/templates/) to change the overall layout and style of your directory:
* **Default New** - Modern default template
* **Aurora** - Gradient-focused design
* **Stellar** - Space-inspired theme
* **Default** - Classic layout
* **Modern** - Clean, contemporary design
* **Compact** - Dense, information-rich layout
* **Whimsy** - Playful, creative style
* **Job Board** - Optimized for job listings
## Themes
Choose from 30+ color themes powered by [DaisyUI](https://daisyui.com/docs/themes/). Themes apply instantly across your entire directory.
### Auto Dark Mode
Enable **Auto Dark Mode** to automatically switch themes based on the user's system preference. You can select which dark theme to use when this is enabled.
Auto Dark Mode is not available for Aurora and Stellar templates as they have their own built-in dark mode handling.
### Font Family
Choose from 10 font families: Poppins, Inter, Roboto, Open Sans, Lato, Montserrat, Source Sans Pro, Nunito, Raleway, Ubuntu.
## Custom Theme
Create your own theme using the [DaisyUI Theme Generator](https://daisyui.com/theme-generator/), then paste the generated CSS into the Custom Theme field:
```css theme={null}
--color-primary: oklch(71% 0.194 13.428);
--color-secondary: oklch(71% 0.202 349.761);
--radius-selector: 0.5rem;
...
```
***
You can also add custom CSS, HTML, and JavaScript to further customize your directory.
# Listings Route
Source: https://docs.directify.app/directories/listings-route
Learn how to customize your directory listings URL structure. Configure custom routes for better SEO and user experience, with automatic redirects for existing links.
The listings route allows you to customize the URL path for your individual listing pages. By default, listings are accessed at `/listings/[listing-slug]`, but you can customize this prefix to match your directory's structure.
## Customizing the Listings Route
To change your listings route:
1. Go to your edit directory page
2. Navigate to the "Listing Route" section
3. Enter your desired route prefix (e.g., "products", "resources", etc.)
4. Click "Save"
For example, if you set the listings route to "products":
* Default URL: `yourdomain.com/listings/awesome-product`
* New URL: `yourdomain.com/products/awesome-product`
Changing the listings route will automatically redirect all existing listing URLs to the new path, so you won't lose any traffic or links.
## Best Practices
When choosing a listings route:
* Use descriptive terms that reflect your content (e.g., "tools", "businesses", "resources")
* Keep it short and memorable
* Use lowercase letters and hyphens only
* Avoid special characters or spaces
The listings route must be unique and cannot conflict with other routes in your directory (like category pages or custom pages).
# Social Links
Source: https://docs.directify.app/directories/social-links
Complete guide to adding and managing social media links in your directory. Learn how to connect various platforms including Facebook, Twitter, Instagram, LinkedIn, and more to enhance your online presence.
Social links help visitors connect with your directory on various platforms. You can add links to your social media profiles and other important URLs to make it easy for users to follow and engage with your brand across different channels.
## Available Social Platforms
You can add links to any of these platforms:
Connect your Facebook page or group
Link your Twitter/X profile
Share your Instagram feed
Add your LinkedIn profile or company page
Feature your YouTube channel
Showcase your TikTok content
Invite users to your Discord server
Link to your GitHub profile or repository
Add any other important URLs
## Adding Social Links
To add social links to your directory:
1. Go to your directory settings
2. Navigate to the "Social Links" section
3. Click "Add Social Link"
4. Select the platform from the dropdown
5. Enter your profile URL
6. Click "Save"
For "Other" links, make sure to include the full URL including `https://`
Your social links will appear in your directory's footer and can help:
* Build your social media following
* Increase brand visibility
* Provide additional ways to contact you
* Share more content with your audience
## Next Steps
After setting up your subdomain, you can further customize your directory:
Connect your own domain name for a more professional look
Add your logo, choose a theme, and customize the design
# Subdomain
Source: https://docs.directify.app/directories/subdomain
Learn how to manage and customize your directory subdomain in Directify. Understand subdomain creation, customization options, and important considerations for URL changes.
After creating your directory, it will receive a default subdomain based on your directory name. This subdomain serves as your directory's unique web address on the Directify platform.
## Subdomain
For example, if your directory name is "Toolhub", your default subdomain will be `toolhub.directify.xyz`. This allows you to immediately share and access your directory online.
You can customize your subdomain at any time by editing your directory's slug in the settings. The slug is the unique identifier in your URL, and changing it will:
* Automatically update your subdomain
* Keep all your listings and categories intact
Changing your slug will NOT redirect your old links to the new URL. So if you shared your directory with others, they will not be able to access it.
Make sure to share the new URL with your audience.
Choose a slug that is:
* Short and memorable
* Contains only letters, numbers, and hyphens
* Reflects your directory's name or purpose
## Next Steps
After setting up your subdomain, you can further customize your directory:
Connect your own domain name for a more professional look
Add your logo, choose a theme, and customize the design
# Team
Source: https://docs.directify.app/directories/team
Comprehensive guide to managing team members in your Directify directory. Learn about different role levels, permissions, and best practices for team collaboration and security.
Team members help you manage your directory by giving them different levels of access. You can add team members with specific roles to collaborate effectively while maintaining security.
## Adding Team Members
To add a team member:
1. Go to your edit directory page
2. Navigate to the "Users" section
3. Click "Add User"
4. Enter their details:
* Email address
* Name
* Role
5. Click "Save"
## Team Member Roles
Directify offers three role levels for team members:
Full access to manage everything except deleting the directory
Can manage listings and categories
Read-only access to view entries
### Role Permissions
Here's a detailed breakdown of what each role can do:
#### Manager
* Add/remove team members
* Manage directory settings
* Edit listings and categories
* View all directory data
* Cannot delete the directory
#### Editor
* Create and edit listings
* Manage categories
* View all directory data
#### Viewer
* View listings and categories
* No editing permissions
* Read-only access
Only the directory owner can delete the directory or change ownership.
## Best Practices
When managing your team:
* Assign roles based on responsibility level
* Regularly review team member access
* Remove team members who no longer need access
* Use viewer roles for temporary access needs
# Create custom forms for lead generation and user engagement
Source: https://docs.directify.app/forms/create-forms
Build custom forms with flexible field types and strategic placement options to capture leads and engage with your directory users
Directify's form builder enables you to create custom forms for lead generation, user feedback, and community engagement. With flexible field types and strategic placement options, you can capture valuable user information and build stronger relationships with your directory audience.
## Form Basics
### Form Configuration
* **Name** - Internal identifier for form management
* **Placement** - Strategic positioning throughout your directory
* **Content Above Form** - Rich text introduction or instructions
* **Content Below Form** - Additional information or disclaimers
* **Submit Button Text** - Customizable call-to-action
* **Custom URL** - Optional external form submission endpoint
* **Published Status** - Enable/disable forms without deletion
## Field Types
### Text Fields
* **Text** - Single-line text input for names, titles, etc.
* **Email** - Email validation with proper formatting
* **Textarea** - Multi-line text for comments and descriptions
* **Number** - Numeric input with validation
* **Date** - Date picker for scheduling and events
### File Upload
* **File** - Document and image upload capability
* Automatic file handling and storage
* Configurable file type restrictions
## Form Placement Options
Forms can be strategically placed throughout your directory for maximum engagement:
### Homepage Integration
Place forms prominently on your directory homepage to capture visitor interest immediately.
### Category Pages
Target specific audiences by placing forms on relevant category pages.
### Listing Pages
Capture leads from users interested in specific listings or services.
### Custom Page Integration
Integrate forms into your custom pages for specialized campaigns.
## Dynamic Field Management
### Field Configuration
Each form field includes:
* **Name** - User-facing label for the field
* **Slug** - Automatically generated database identifier
* **Type** - Field input type selection
* **Required Status** - Optional or mandatory field designation
* **Reorderable Fields** - Drag-and-drop field organization
### Smart Field Generation
* **Auto-slug Creation** - Automatic database-friendly field names
* **Live Updates** - Real-time slug generation from field names
* **Field Validation** - Built-in validation for email and number fields
## Lead Management
### Lead Collection
* **Automatic Storage** - All form submissions stored securely
* **Lead Count Display** - Real-time submission tracking
* **Data Organization** - Structured lead information for easy review
### Lead Access
* **Relation Manager** - Built-in lead viewing and management
* **Export Capabilities** - Download lead data for external processing
* **Search and Filter** - Find specific leads quickly
## Content Customization
### Rich Text Editing
Both content areas (above and below form) support:
* **Rich Text Editor** - Professional formatting options
* **File Attachments** - Images and documents
* **Media Integration** - Embedded content support
* **Automatic Storage** - File management with proper visibility
### Flexible Messaging
* **Introduction Content** - Set context and expectations
* **Disclaimer Content** - Legal information and terms
* **Custom Styling** - Match your directory's design
* **Mobile Optimization** - Responsive content display
## Advanced Features
### Custom Submission Handling
* **External URLs** - Send form data to external services
* **Webhook Integration** - Real-time form submission notifications
* **API Connectivity** - Connect with third-party systems
### Form Analytics
* **Submission Tracking** - Monitor form performance
* **Conversion Rates** - Understand user engagement
* **Field Analytics** - Identify completion patterns
## Best Practices
1. **Clear Purpose** - Make form objectives obvious to users
2. **Minimal Fields** - Request only essential information
3. **Mobile Optimization** - Test forms on mobile devices
4. **Privacy Transparency** - Clearly explain data usage
5. **Thank You Messages** - Provide confirmation and next steps
Form fields are automatically reorderable using drag-and-drop functionality, allowing you to optimize the user experience based on your specific needs.
## Integration Examples
### Newsletter Signup
Create simple email capture forms for newsletter subscriptions and updates.
### Contact Forms
Build comprehensive contact forms for user inquiries and support requests.
### Lead Qualification
Develop detailed forms to qualify potential customers or partners.
### Event Registration
Create registration forms for directory-related events and meetups.
***
Connect forms to external services
Create landing pages for your forms
# BlogBuster
Source: https://docs.directify.app/integrations/blogbuster
Comprehensive guide to BlogBuster integration. Learn how to automate your blog posts with BlogBuster.
# 🔗 BlogBuster Integration with Directify
Easily connect **[BlogBuster](https://blogbuster.so/)** with your Directify project to generate **SEO-optimized blog posts** directly inside your dashboard.
***
## 🚀 What is BlogBuster?
BlogBuster is an AI-powered blog generator that creates **high-quality, SEO-optimized content** in minutes. With this integration, you can:
* Generate articles tailored to your directory.
* Automatically optimize content for SEO.
* Publish directly from Directify.
* ✅ Have all articles **pulled automatically once a day** – no manual work required.
***
## 🛠️ How to Set Up
### 1. Get Your BlogBuster API Key
1. Log in to your **BlogBuster Dashboard**.
2. Go to **Settings → API Keys**.
3. Copy your API key.
***
### 2. Add Your API Key in Directify
1. Open your **Directify Admin Dashboard**.
2. Navigate to **Settings → Integrations**.
3. Find **BlogBuster**.
4. Paste your **API Key** in the input field.
* 🔒 Your key is stored securely.
* You can click **Reveal** to double-check.
***
### 3. Get Your Tenant ID
1. Click the **Get Tenants** button.
2. Directify will fetch your tenants from BlogBuster.
3. Select your **Tenant** from the dropdown list.
***
## ⚡ Automatic Sync
* Directify will **pull new articles from BlogBuster once per day**.
* You don’t need to do anything – your directory content stays updated automatically.
* Articles will appear in your dashboard, ready to review or publish.
***
# ConvertHub Integration
Source: https://docs.directify.app/integrations/converthub
Complete guide to integrating ConvertHub with Directify. Compress listing and directory images from PNG/JPG to WebP for faster pages, better Core Web Vitals scores, and a smaller CDN footprint.
Compress and convert your listing and directory images to modern WebP in one click with [ConvertHub](https://converthub.com). This integration shrinks PNG/JPG uploads by up to 70% without changing a single listing URL, lifting Core Web Vitals scores and reducing CDN bandwidth across your directory.
## Key Features
* **Convert PNG and JPG → WebP** at any scale, from a single listing to thousands across your directory
* **Per-category dashboard** — pick exactly which surface to optimize: Listings, Directory branding, Articles, or Organizers
* **Live ConvertHub credit balance** — see remaining credits in the dashboard header before you spend
* **In-place replacement** — the listing or article URL stays the same, only the file gets smaller
* **One-click retry on failure** — failed conversions land in a dedicated table with a Retry action per row
* **Manual control** — no conversion ever runs automatically on upload, so you stay in charge of credit spend
## Setup
To enable ConvertHub integration:
1. Create a [ConvertHub account](https://converthub.com/api/signup)
2. Grab your API key from the developer dashboard
3. Go to **Settings → Integrations** inside Directify
4. Paste your API key into the **ConvertHub** section and click **Save** — Directify validates the key with ConvertHub before storing it (encrypted at rest)
5. Open the new **Settings → Image Optimization** page that appears once the key is saved
## How It Works
### Eligible images
Directify scans your directory and counts every PNG/JPG that has not already been optimized. WebP and AVIF originals are skipped automatically, so the eligible count is always honest.
### Optimize on demand
The Image Optimization dashboard groups your images into four category cards: **Listings**, **Directory branding**, **Articles**, and **Organizers**. Each card shows how many images are eligible, how many are already optimized, how many are queued, and how much storage you have already saved. Click **Optimize** on any card and Directify queues a background job per image.
### Background conversion
Each job submits the source URL to ConvertHub, polls until the conversion is ready, downloads the WebP, and swaps the file in place on your CDN. The database column is updated atomically so visitors always see a valid image — there is no in-between state.
### Failure handling
If a conversion fails (out of credits, network blip, unsupported source), the original image is left untouched and the failure shows up in a **Failed optimizations** table with a one-click **Retry** action per row. You can retry individual failures at any time.
### Plan gating
ConvertHub sits behind the same `integrations` plan feature as Google Sheets, OpenAI, SEOBot, and BlogBuster. If your plan already includes integrations, ConvertHub is available immediately under **Settings → Integrations**.
API usage is billed directly by ConvertHub based on your account plan. Directify does not mark up conversions — every credit you spend goes to ConvertHub at their published price. Most simple PNG/JPG → WebP conversions cost a single credit.
No conversion ever runs automatically on upload. Every optimization is an explicit click in the dashboard, so you stay in full control of credit spend and image quality.
With [ConvertHub](https://converthub.com), you can shrink your image footprint, speed up your pages, and lift SEO scores — without changing a single listing URL.
# Google Chrome Extension
Source: https://docs.directify.app/integrations/google-chrome-extension
Complete guide to using the Directify Chrome Extension. Learn how to generate API keys, install the extension, and save websites to your directory with one click, including bulk saving and automatic metadata collection.
# Using the Chrome Extension
Our Chrome Extension allows you to save websites to your Directify directory with just one click. Here's how to set it up and use it effectively.
## 1. Generate Your API Key
Before using the extension, you need to create an API key:
1. Go to **Settings → API** in your dashboard
2. Click the key icon to generate a new API key
3. Copy your API key immediately (it will only be shown once)
4. You can manage all your API keys from this screen
Make sure to save your API key in a secure location as it will only be displayed once.
## 2. Connect the Extension
After generating your API key:
1. Install the Chrome Extension from the Chrome Web Store [here](https://chromewebstore.google.com/detail/cfmljcoemdlhghelinplaheifiipljpn)
2. Paste your API key into the input field
3. Your directories will automatically load inside the extension
## 3. Save Websites to Your Directory
When browsing the web:
1. Click on the Extension Icon in Chrome
2. Select the Directory you want to save the website to
3. Optionally choose a Category (or leave empty)
4. Click **Save**
That's it! The website will be added to your selected directory.
## 4. Bulk Saving Made Easy
To speed up adding multiple listings:
* The extension remembers your last selected directory and category
* No need to reselect for each new website
* You can change selections at any time before saving
## 5. Data Collection
The extension automatically fetches:
* Title
* Description
* Icon (favicon)
* Other available metadata from the URL
If a URL is not publicly accessible (behind login walls, etc.), data collection might fail for that specific page.
## Get Started
That's all you need to know to start using the Chrome Extension with Directify. Enjoy the seamless experience of building your directory as you browse!
# Google Sheets Integration
Source: https://docs.directify.app/integrations/google-sheets
Complete guide to integrating Google Sheets with Directify. Learn how to sync listings with automatic two-way synchronization, create templates, handle images, and automate daily updates for efficient directory management.
Integrating Google Sheets with Directify has been a highly requested feature, and it is now available!
This integration allows users to create directories from Google Sheets, back up their data, and seamlessly sync listings between Directify and Google Sheets.
Here's a detailed guide on how to set it up and use it effectively.
## **Connecting Google Sheets Integration**
You can connect Google Sheets to Directify in two ways:
1. **Through Listings:** Navigate to your listings and connect directly.
2. **Through Settings:** Go to *Settings > Integrations* and connect your Google Sheets API.
For this guide, we'll use the Listings method.

### **Step 1: Connecting Google Sheets**
Once you initiate the integration, a Google authentication screen will appear, prompting you to grant access to Google Sheets. After granting access, Directify will connect to your Google account, enabling you to create directories from Google Sheets effortlessly.
### **Step 2: Creating a Template**
After connecting, you must create a template. This ensures that all necessary fields, including listing fields, categories, tags, and custom fields, are included in your Google Sheet.

> You can also manually connect your Google Sheets URL, but it will not automatically include the required fields. If you only need specific details like *name* and *URL*, you can use this option. However, using the *Create Template* function is recommended for a complete data set.
### **Step 3: Populating Your Google Sheet**
Once the template is created, you can:
* Manually populate the fields and add listings in Google Sheets.
* Push existing listings from Directify to Google Sheets using the "Push to Google Sheets" button.
* Pull listings from Google Sheets to Directify using the "Pull from Google Sheets" button.
## **Two-Way Synchronization**
Two-way synchronization is now **automatically enabled** for all Google Sheets integrations. This means:
* Changes made in Directify can be pushed to Google Sheets.
* Changes made in Google Sheets can be pulled into Directify.
* Data stays in sync between both platforms.
### **Manual Sync Options**
You can manually sync your data at any time using two options:
* **Push to Google Sheets:** Uploads the latest data from Directify to Google Sheets.
* **Pull from Google Sheets:** Fetches the latest data from Google Sheets into Directify.
**Sync Limitation:** You can only sync every 12 hours. This includes the automated daily sync at midnight UTC. If you try to sync before 12 hours have passed, the buttons will be disabled.
### **Image Handling Options**
When syncing listings, you have two mutually exclusive options for handling images:
1. **Auto-Screenshot Listings:** Automatically captures screenshots from listing URLs when syncing. This requires the ScreenshotOne integration to be enabled.
2. **Re-Upload Images from URLs to Internal Storage:** Downloads images from `logo_url` and `image_url` columns in your Google Sheet and stores them in your internal media library. Only downloads if no existing image is uploaded.
These options are mutually exclusive - enabling one will automatically turn off the other. Choose the option that best fits your workflow.
### **Updating Listings**
To update a listing:
1. Edit the relevant field in Google Sheets (e.g., change "Larafast" to "Larafast Updated Name").
2. Click **Pull from Google Sheets** in Directify to fetch the updates.
3. The changes will be reflected in your Directify directory.
Similarly, updates made in Directify can be pushed back to Google Sheets using the **Push to Google Sheets** button.
**Pro Tip:** If you leave the **slug** column blank in Google Sheets, Directify will automatically generate it after syncing. The auto-generated slug will then be synced back to your Google Sheet for future matching.
## **Automated Daily Sync**
Directify automatically runs a sync every midnight (UTC) to ensure all changes in Google Sheets are reflected in your directory. This automated sync counts toward the 12-hour sync limitation.
If you need updates between the automated syncs, you can manually pull or push data at any time, as long as 12 hours have passed since the last sync.
## **Final Thoughts**
This Google Sheets integration is a simple yet powerful tool for managing and backing up your Directify listings. Whether you need a real-time sync, want to create a directory from Google Sheets, or even build a website from Google Sheets, this feature enhances efficiency and ensures your data is always up-to-date.
Cheers, and happy listing!
# OpenAI Integration
Source: https://docs.directify.app/integrations/openai
Learn how to integrate OpenAI with Directify to generate AI-powered content. Set up API keys, enable automated content generation, and create SEO-optimized titles and descriptions for your listings.
OpenAI integration allows you to leverage AI to automatically generate and enhance SEO content for your listings, categories, and blog posts. This includes descriptions, titles, and other text content powered by GPT models.
## Setup
To enable OpenAI integration:
1. Create an [OpenAI account](https://platform.openai.com)
2. Get your API key from the OpenAI dashboard
3. Go to your directory settings
4. Navigate to "Integrations"
5. Enable OpenAI and enter your API key
6. Save changes
## Features
With OpenAI integration enabled, you can create SEO-optimized titles and meta descriptions for your listings, categories, and blog posts
AI content coming soon.
API usage is billed directly by OpenAI based on your account's pricing plan.
# ScreenshotOne Integration
Source: https://docs.directify.app/integrations/screenshotone
Complete guide to integrating ScreenshotOne with Directify. Learn how to automatically generate and optimize website screenshots for your listings, both manually and through bulk imports.
Automatically generate high-quality website screenshots for your listings with [ScreenshotOne](https://screenshotone.com/?ref=directify). This integration gives you fast, reliable screenshots without needing to upload images manually, helping your directory look polished and consistent.
## Key Features
* **Auto-generate screenshots** for websites when adding new listings
* **Manual capture** with a single click while editing any listing
* **Bulk import automation** — automatically capture screenshots during CSV imports
* **Bulk Screenshots for Selected Listings** — select multiple listings in your directory and generate screenshots for all of them at once
* **Optimized storage** — all screenshots are saved and compressed in your media library
## Setup
To enable ScreenshotOne integration:
1. Create a [ScreenshotOne account](https://screenshotone.com/?ref=directify)
2. Grab your API key and secret from the ScreenshotOne dashboard
3. Go to **Settings → Integrations** inside Directify
4. Enter your API credentials and save the integration
## How It Works
### Manual Screenshots
Click the camera icon next to the cover image field when creating or editing a listing. This will instantly capture a screenshot of the website URL.
### Bulk Screenshots (Selected Listings)
In the listings table, select multiple items and choose the **"Generate Screenshot"** bulk action. This allows you to generate screenshots for multiple listings at once, saving time when managing large directories.
### Automatic Import
When importing via CSV, enable the auto-screenshot option and Directify will capture everything automatically. This ensures every imported listing has a professional preview without manual intervention.
Screenshots are only generated for listings with valid URLs.
With [ScreenshotOne](https://screenshotone.com/?ref=directify), you can ensure every listing has a clean, professional preview — no extra effort needed.
# SEO Bot AI Integration – Automated Directory Blog
Source: https://docs.directify.app/integrations/seobotai
Connect SEO Bot AI to your Directify directory to automatically generate and publish optimized blog posts on autopilot — full setup guide.
# SEO Bot AI Integration
SEOBot is an advanced AI-powered "SEO Robot" that automatically generates SEO-optimized blog posts for your business. By integrating SEOBot with Directify, you can streamline your content creation process and maintain a consistent publishing schedule.
## Features
* **AI-Powered Content Generation**: Automatically creates SEO-friendly blog posts
* **Daily Content Sync**: Automatic synchronization of new blog posts
* **SEO Optimization**: Built-in keyword optimization and content structure
* **Customizable Topics**: Control the focus and direction of your content
* **Content Quality**: High-quality, readable, and engaging blog posts
## Prerequisites
Before you begin, ensure you have:
* An active SEOBot account
* Access to your Directify dashboard
* Admin permissions in your Directify workspace
## Integration Steps
1. **Create SEOBot Account**
* Visit [SEOBot website](https://seobotai.com)
* Sign up for an account
* Complete your profile setup
2. **Generate API Key**
* Log in to [SEOBot dashboard](https://app.seobotai.com)
* Navigate to Menu → Blog Sync Status
* Click on "REST API Key"
* Copy your generated API key
3. **Connect to Directify**
* Log in to your [Directify dashboard](https://directify.app/app)
* Go to Settings → Integrations
* Find and select "SEOBot"
* Paste your API key in the designated field
* Click "Save" to complete the integration
## How It Works
Once connected, Directify will:
* Automatically sync with SEOBot once per day
* Import new blog posts to your Directify account
* Maintain your content calendar
* Keep your blog updated with fresh, SEO-optimized content
## Best Practices
* Regularly review your SEOBot settings to ensure content aligns with your business goals
* Monitor your blog's performance metrics after integration
* Update your content strategy based on performance data
* Keep your API key secure and don't share it publicly
## Troubleshooting
If you encounter any issues:
1. Verify your API key is correctly copied
2. Ensure your SEOBot account is active
3. Check your internet connection
4. Contact SEOBot support if problems persist
# Webhooks
Source: https://docs.directify.app/integrations/webhooks
Comprehensive guide to Directify webhooks integration. Learn how to set up real-time notifications, verify signatures, handle events, and implement best practices for listings, leads, categories, and more.
Webhooks allow you to receive real-time notifications when events occur in your Directify account. When an event occurs, we'll send an HTTP POST request to the URL you specify.
## Security
Each webhook request includes a signature in the `X-Directify-Signature` header. You should verify this signature to ensure the request came from Directify.
### Verifying Signatures
Here's how to verify the signature:
```php theme={null}
// PHP example
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_DIRECTIFY_SIGNATURE'];
$secret = 'your_webhook_secret';
$calculatedSignature = hash_hmac('sha256', $payload, $secret);
if (hash_equals($calculatedSignature, $signature)) {
// Signature is valid
} else {
// Signature is invalid
}
```
## Request Format
All webhook requests are sent as HTTP POST requests with a JSON payload. The following headers are included:
* `Content-Type: application/json`
* `X-Directify-Signature`: HMAC SHA-256 signature
* `X-Directify-Event`: The name of the event (e.g., `project.created`)
## Payload Format
The payload includes the following fields:
| Field | Description |
| ----------- | ------------------------------------------------------------------ |
| `event` | The name of the event |
| `timestamp` | The Unix timestamp when the event occurred |
| `id` | The ID of the affected resource |
| `model` | The type of resource (e.g., Project) |
| `data` | The full resource data |
| `changes` | For update events, the fields that were changed (before and after) |
For listings, the `model` will be `Project`, and the events are also prefixed with `project` as that's how we handle them internally.
## Available Events
The following events are available:
| Event | Description |
| ------------------ | ---------------- |
| `project.created` | Listing Created |
| `project.updated` | Listing Updated |
| `project.deleted` | Listing Deleted |
| `lead.created` | Lead Created |
| `lead.updated` | Lead Updated |
| `lead.deleted` | Lead Deleted |
| `category.created` | Category Created |
| `category.updated` | Category Updated |
| `category.deleted` | Category Deleted |
| `ad.created` | Ad Created |
| `ad.updated` | Ad Updated |
| `ad.deleted` | Ad Deleted |
| `article.created` | Article Created |
| `article.updated` | Article Updated |
| `article.deleted` | Article Deleted |
| `tag.created` | Tag Created |
| `tag.updated` | Tag Updated |
| `tag.deleted` | Tag Deleted |
## Best Practices
* Always verify the signature of incoming webhook requests
* Implement idempotency to handle duplicate webhook deliveries
* Respond quickly to webhook requests (within 5 seconds)
* Implement proper error handling for webhook processing
# Welcome to Directify Documentation
Source: https://docs.directify.app/introduction
Comprehensive guide to building and managing directory websites with Directify. Learn how to create directories, add listings, customize themes, and connect domains without any coding knowledge.
Directify is a no-code platform for building and managing directory websites. Whether you're creating a business directory, resource list, or community hub, Directify enables you to launch your directory in minutes without any technical expertise.
## Setting up
The first step to world-class documentation is setting up your editing environments.
Set up your directory name, logo, and theme
Import or manually add listings and categories
Link your custom domain
## Support
This documentation will guide you through setting up, customizing, and managing your Directify directory.
For support, reach out to [sergey@directify.app](mailto:sergey@directify.app) or join our [Discord Community](https://discord.gg/B9hTD4kAJY)
# Add listings to your online directory
Source: https://docs.directify.app/listings/add-listing
Learn how to create and manage business listings with detailed fields for contact info, media, categories, and visibility settings to build a comprehensive online directory
Your online directory listings are powerful tools for showcasing businesses, resources, or items in your business directory website. Each listing can be enriched with comprehensive information to provide value to your directory visitors. Here's a detailed overview of all available fields:
### Basic Information
* **Name** (Required) - The primary identifier for your listing that appears in search results and headers
* **Description** - A comprehensive overview that helps visitors understand what you're offering in your online directory
* **Categories** - Strategic organization tools that improve navigation and discoverability in your business directory
* **Tags** - Additional classification keywords that enhance search functionality
* **Content** - A versatile markdown-enabled section where you can:
* Create structured, formatted content
* Incorporate high-resolution images and videos
* Integrate external media through YouTube/Vimeo embeds
### Contact Details
* **Phone Number** - Professional contact number with international format support (e.g., +1234567890)
* **Email** - Direct communication channel for inquiries and correspondence
* **Address** - Physical location details with optional map integration
### Web Presence
* **URL** - Primary website link with intelligent auto-fill functionality
* **Social Links** - Comprehensive social media integration:
* Multiple platform support (Twitter, Facebook, LinkedIn, etc.)
* Direct profile linking
* Customizable display order
### Media
* **Logo** - Brand identity through direct upload or URL reference
* **Cover Image** - Primary visual representation for your listing
* **Screenshot** - Automated website capture capability for enhanced visual presence
Website screenshot functionality requires ScreenshotOne integration activation in your settings.
Explore the complete [ScreenshotOne integration guide](/integrations/screenshotone).
### Visibility Settings
* **Published** - Control public visibility of your listing
* **Featured** - Priority placement for premium listings in your directory website
* **No Follow** - Advanced SEO control for external link management
## Strategic Tips
1. Utilize the URL auto-population feature for efficient listing creation
2. Implement a structured category and tag system to organize your online directory
3. Leverage markdown formatting for professional content presentation
4. Maintain current contact information for reliable user engagement
5. Prioritize high-quality visual assets to create an engaging business directory website
Featured listing functionality requires specific configuration in Directory Settings for optimal display management.
***
Learn about importing listings
Learn about ScreenshotOne integration
Learn about SEO
Learn about Custom Fields
# Add Custom Fields to Your Directory Listings
Source: https://docs.directify.app/listings/custom-fields
Extend Directify listings with custom fields — capture pricing, hours, ratings, files, or any data your directory needs beyond the defaults.
Custom fields allow you to extend your listings with additional information specific to your directory needs. You can create custom fields to capture and display any type of data that's relevant for your listings.
## Creating Custom Fields
When creating a custom field, you'll need to configure several settings:
### Basic Settings
* **Resource** - Currently only Listing resource is supported
* **Name** - Database field name (e.g., "working\_hours")
* **Label** - Display name shown to users (e.g., "Working Hours")
* **Type** - Field type options:
* Text - Single-line text input
* Number - Numeric values
* Date - Date picker
* File Upload - File attachments
* URL - Link with validation
* Email - Email with validation
* Rich Editor - Visual rich text editor
* Markdown - Markdown editor
* Textarea - Multi-line text
* Checkbox - True/false toggle
* Rating - Star rating input
* Select - Dropdown with custom options
* List - Multiple values as a list
* Button - Clickable button field
* **Placeholder** - Example text shown in input (e.g., "10:00 - 18:00")
* **Description** - Helper text explaining the field
* **Default Value** - Pre-filled value for new listings
### Placement Options
Control where the field appears on the listing page: After Tags, After Categories, Before Content, After Content.
For listing cards: Before Categories, After Categories, Before Buttons, After Buttons.
### Icons
You can add an icon to your custom field:
* **Heroicon** - Select from the Heroicon library (takes priority)
* **Custom Icon** - Upload your own icon as a fallback
### Visibility Settings
Fine-tune how the field is displayed:
* **Is Required** - Make the field mandatory for submissions
* **Show on Card** - Display field value on listing cards
* **Is Visible** - Control overall field visibility
* **Show Label** - Display field label on listing page
* **Show Label on Card** - Display field label on listing cards
* **Show on Public Submission** - Allow field input on public submission forms
* **Show Icon** - Display icon on listing page
* **Show Icon on Card** - Display icon on listing cards
* **Filterable** - Available for Number, Checkbox and Date fields. Enables filtering on listings page
### Design Settings
Customize the appearance of each custom field with the Design Settings button:
* **Icon** - Size (Extra Small to XXL) and color (Primary, Secondary, Accent, etc.)
* **Label** - Size (text-xs to text-2xl) and color
* **Value** - Size and color
* **Custom Classes** - Add your own Tailwind classes for full control
Custom fields are a powerful way to tailor your directory to specific industries or use cases. For example, you could add fields for:
* Business hours (Text/Rich Editor)
* Price ranges (Number)
* Certifications (File Upload)
* Service areas (Textarea)
* Terms acceptance (Checkbox)
* And more
# Import and Export Directory Listings via CSV
Source: https://docs.directify.app/listings/import-export
Bulk import and export listings for your Directify directory using CSV — the fast way to populate a new directory or migrate existing data.
Directify provides powerful import and export capabilities to help you manage your listings in bulk. You can easily import listings from a CSV file and export your existing listings to CSV format.
## Importing Listings
To import listings into your directory:
1. Download the example CSV file to see the correct format
2. Prepare your CSV file with the following columns:
### Required Fields
* **name** - The listing name (required, max 255 characters)
### Optional Fields
* **description** - A brief description of the listing
* **content** - Detailed content/body text for the listing
* **url** - Website URL (max 255 characters)
* **phone\_number** - Contact phone number (max 255 characters)
* **email** - Contact email address (max 255 characters)
* **address** - Physical address (max 255 characters)
* **tags** - Comma separated list of tags (max 255 characters)
* **is\_no\_follow** - SEO nofollow setting (1/0, true/false, yes/no, y/n)
* **is\_featured** - Featured listing status (1/0, true/false, yes/no, y/n)
* **is\_active** - Published status (1/0, true/false, yes/no, y/n)
* **logo\_url** - URL to listing logo image (max 255 characters)
* **image\_url** - URL to listing cover image (max 255 characters)
**Important:** The boolean fields (is\_no\_follow, is\_featured, is\_active) should be set to 1 (true) or 0 (false) or y (yes) or n (no).
### Import Settings
When importing, you can configure:
1. **Categories** - Assign imported listings to specific categories
2. **Update Existing** - Choose whether to update existing records
3. **Default Publishing** - Set whether imported listings should be published by default (this will override the is\_active field in the CSV file)
Make sure your CSV file uses UTF-8 encoding for proper handling of special characters.
### Import Results
After the import completes, you'll see a notification in the top-right corner with:
* Number of successfully imported articles
* Number of failed imports
* Option to download detailed results
The results file includes all attempted imports with status and error messages. To review failures:
1. Download the results CSV
2. Scroll right to see the "Error" column
3. Review specific error messages for each failed row
Common error messages include:
* Invalid title length
* Missing required fields
* Malformed dates
* Invalid URLs
Use the error messages to correct issues in your import file, then retry importing the failed rows.
## Exporting Listings
You can export all your listings to CSV format for backup or bulk editing purposes. The exported file will contain all the fields listed above.
Large directories may take a few moments to export. The system will notify you once your export is ready for download.
# Related Articles for Directory Listings
Source: https://docs.directify.app/listings/related-articles
Connect blog articles to your Directify directory listings as related content — boost SEO, improve internal linking, and add depth to listings.
Related articles allow you to connect existing articles to your listings, creating valuable cross-references and additional context for your directory visitors. These related articles appear below the main listing content.
## Adding Related Articles
To add related articles to a listing:
1. Navigate to the listing edit page
2. Scroll to the "Related Articles" section
3. Search and select articles from your directory
4. Arrange articles in your preferred order
5. Save the listing to update relationships
## Benefits
* **Enhanced Value** - Provide additional relevant content to visitors
* **Better Navigation** - Create natural pathways between related content
* **SEO Benefits** - Internal linking helps search engines understand content relationships
* **Increased Engagement** - Keep visitors exploring more of your directory content
Related articles are displayed with their title, description, and thumbnail image (if available). Visitors can click through to read the full article content.
## Best Practices
1. Choose articles that are truly relevant to the listing
2. Keep the number of related articles focused (3-5 is often ideal)
3. Regularly review and update article relationships
4. Use related articles to highlight key resources or guides
Deleting an article will automatically remove it from any listings where it was set as a related article.
# Manage tags for your directory listings
Source: https://docs.directify.app/listings/tags
Learn how to create, customize, and manage tags for better listing organization and enhanced user navigation in your directory
Tags provide an additional layer of organization for your directory listings, helping users discover related content and improving the overall navigation experience. Unlike categories, tags are more flexible and can be applied across multiple listings regardless of their primary category.
## Creating and Managing Tags
### Basic Tag Information
* **Title** (Required) - The tag name that appears on your listings (without the # symbol - this is automatically added)
* **Slug** - Automatically generated URL-friendly version of your tag title
* **Color** - Custom background color for your tag badges
* **Text Color** - Custom text color for optimal readability
* **Icon** - Optional visual icon to accompany your tag
### Visual Customization
Tags in Directify are highly customizable to match your directory's design:
#### Color Scheme
* **Background Color** - Set a unique color for each tag to create visual distinction
* **Text Color** - Ensure proper contrast and readability
* **Icon Support** - Upload custom icons to make tags more visually appealing
#### Display Options
* **Show Title** - Control whether the tag text is visible (enabled by default)
* **Show Icon** - Toggle icon visibility on listings pages
* **Active Status** - Enable or disable tags without deleting them
## Tag Implementation
### On Listing Pages
Tags appear on individual listing pages to help users:
* Identify related topics and themes
* Navigate to similar listings
* Understand listing characteristics at a glance
### On Listing Cards
In the listings grid/list view, tags provide:
* Quick visual identification
* Filtering and discovery capabilities
* Enhanced categorization beyond primary categories
## Best Practices
1. **Consistent Naming** - Use clear, descriptive tag names that users will easily understand
2. **Color Strategy** - Develop a color scheme that aligns with your directory's branding
3. **Icon Usage** - Use icons sparingly for the most important tags to avoid visual clutter
4. **Regular Review** - Periodically review and consolidate similar or redundant tags
## Advanced Features
### Tag Filtering
Users can filter listings by tags, making it easier to find specific types of content within your directory.
### Search Integration
Tags are indexed for search functionality, helping users discover relevant listings through tag-based queries.
### Analytics
Track which tags are most popular to understand user interests and optimize your tagging strategy.
***
Learn about adding custom fields to listings
Understand category management
# Custom Payment Links – PayPal, Razorpay, Stripe
Source: https://docs.directify.app/paid-submissions/custom-payment
Use PayPal, Razorpay, Stripe Payment Links, Square, or any external payment provider with Directify paid submissions via custom payment links.
Any payment processor that supports payment links will work (PayPal, RazorPay, Square, Stripe Payment Links, etc.). Just create your payment links and configure plans manually.
## Setup
1. Go to **Settings** → **Paid Submissions**
2. Enable **Paid Submissions**
3. Select **Custom (PayPal, RazorPay or other)**
## Create Plans
For each plan, configure:
* **Name** - Plan display name
* **Price** - Amount and currency symbol
* **Payment Link** - URL to your payment processor (e.g., `https://paypal.me/yourbusiness/29`)
* **Button Text** - CTA text (e.g., "Buy Now")
* **Is Subscription** - Toggle for recurring payments
* **Features** - List of included/excluded features
## Payment Flow
1. User submits listing and selects a plan
2. User is redirected to your payment link
3. User completes payment externally
4. You manually verify payment and approve the listing
Since payment links don't support webhooks, you'll need to manually check your payment processor and approve listings after payment confirmation.
***
Automated payment processing with Stripe
Global tax-compliant payments with Lemon Squeezy
# Lemon Squeezy Integration for Paid Submissions
Source: https://docs.directify.app/paid-submissions/lemonsqueezy
Connect your Lemon Squeezy account to start accepting paid submissions with seamless integration and automatic plan synchronization.
Lemon Squeezy provides a modern, developer-friendly payment platform perfect for digital businesses. This guide will walk you through integrating Lemon Squeezy with your directory to accept paid submissions with both subscription and one-time payment options.
## Why Choose Lemon Squeezy?
### Key Benefits
* **Global Tax Compliance** - Automatic VAT/tax handling for worldwide sales
* **Merchant of Record** - Lemon Squeezy handles all tax compliance
* **Simple Setup** - Streamlined integration process
* **Flexible Pricing** - Support for subscriptions and one-time payments
* **Developer-Friendly** - Modern API with excellent documentation
## 1. Enable Paid Submissions
Before integrating Lemon Squeezy, you need to enable paid submissions in your directory:
1. Navigate to **Settings** → **Paid Submissions**
2. Toggle **Enable Paid Submissions** to ON
3. Select **Lemon Squeezy** as your payment provider
## 2. Create Your Lemon Squeezy Account
If you don't have a Lemon Squeezy account yet:
1. Visit [Lemon Squeezy](https://lemonsqueezy.com) and sign up
2. Complete your store setup and verification process
3. Create your first store (you'll need the Store ID later)
## 3. Obtain API Credentials
### API Key
1. Log in to your [Lemon Squeezy Dashboard](https://app.lemonsqueezy.com)
2. Navigate to **Settings** → **API**
3. Click **Create API Key**
4. Give your key a descriptive name (e.g., "Directify Integration")
5. Copy the generated API key and save it securely
### Store ID
1. In your Lemon Squeezy dashboard, go to **Settings** → **Stores**
2. Find your store and note the **Store ID** (visible in the URL or store details)
## 4. Configure Lemon Squeezy Integration
### Enter API Credentials
1. In your directory's **Paid Submissions** settings
2. Paste your **API Key** in the designated field
3. Enter your **Store ID**
4. Generate or enter a **Webhook Secret** (use the generate button for security)
### Webhook Configuration
1. Copy the **Webhook URL** provided in your directory settings
2. In Lemon Squeezy, go to **Settings** → **Webhooks**
3. Click **Create Webhook**
4. Paste the webhook URL from your directory
5. Enter the webhook secret you generated
6. Select the following events:
* **Order events**: `order_created`, `order_refunded`
* **Subscription events**: `subscription_created`, `subscription_updated`, `subscription_cancelled`
7. Save the webhook
## 5. Create Products in Lemon Squeezy
### For One-Time Payments
1. Go to **Products** in your Lemon Squeezy dashboard
2. Click **New Product**
3. Choose **Digital Product**
4. Set up your product details:
* **Name**: e.g., "Directory Listing Submission"
* **Price**: Set your desired amount
* **Description**: Describe what customers get
5. Configure checkout settings as needed
6. Publish your product
### For Subscription Plans
1. In **Products**, click **New Product**
2. Choose **Subscription**
3. Configure your subscription:
* **Name**: e.g., "Monthly Directory Listing"
* **Billing Cycle**: Monthly, yearly, etc.
* **Price**: Set subscription amount
* **Description**: Detail subscription benefits
4. Set up trial periods if desired
5. Publish your subscription
## 6. Sync Plans with Your Directory
### Automatic Plan Import
1. In your directory's Paid Submissions settings
2. Click **Verify Credentials and Pull Plans**
3. Confirm the action when prompted
4. Your Lemon Squeezy products will be automatically imported
### Plan Configuration
Once imported, you can customize each plan:
* **Description**: Modify the plan description for your directory
* **Button Text**: Customize the call-to-action text
* **Features**: Add or modify feature lists
* **Bestseller**: Mark popular plans as bestsellers
* **Visibility**: Hide plans you don't want to offer
Pulling plans from Lemon Squeezy will override any existing plans in your directory. Make sure to backup any custom configurations before syncing.
## 7. Test Mode vs Live Mode
### Test Mode
* Lemon Squeezy automatically provides test products for development
* Test mode is indicated by a warning badge in your directory settings
* No real money is processed in test mode
* Perfect for testing the complete payment flow
### Live Mode
* Switch to live products in your Lemon Squeezy dashboard
* Re-sync plans to pull live products
* Real payments will be processed
* Ensure all webhooks are working correctly
## 8. User Payment Experience
### Submission Flow
1. User submits their listing to your directory
2. They're redirected to the submission dashboard
3. Available plans are displayed with pricing and features
4. User selects a plan and clicks the payment button
5. They're redirected to Lemon Squeezy's secure checkout
6. After successful payment, they return to your directory
7. Listing is processed according to your approval settings
### Customer Benefits
* **Secure Payments** - Industry-standard security
* **Global Support** - Automatic currency conversion
* **Tax Handling** - Automatic VAT/tax calculation
* **Receipt Management** - Automatic invoice generation
* **Payment Methods** - Credit cards, PayPal, and more
## 9. Revenue and Analytics
### Lemon Squeezy Dashboard
* **Revenue Tracking** - Real-time sales data
* **Customer Management** - Subscriber and customer lists
* **Analytics** - Detailed sales analytics
* **Tax Reports** - Automatic tax reporting
* **Payout Management** - Flexible payout options
### Directory Integration
* **Automatic Updates** - Subscription status synced via webhooks
* **Payment Verification** - Real-time payment confirmation
* **User Management** - Automatic user access control
## 10. Advanced Features
### Discount Codes
1. Create discount codes in Lemon Squeezy
2. Codes work automatically at checkout
3. Track usage in Lemon Squeezy analytics
### Affiliate Program
* Set up affiliate programs in Lemon Squeezy
* Earn commissions from referrals
* Track affiliate performance
### Custom Checkout
* Customize checkout appearance
* Add your branding
* Configure checkout fields
## Troubleshooting
### Common Issues
#### Plans Not Syncing
* Verify API key has correct permissions
* Check Store ID is accurate
* Ensure products are published in Lemon Squeezy
#### Webhook Not Working
* Verify webhook URL is accessible
* Check webhook secret matches
* Ensure all required events are selected
#### Test Mode Warning
* Switch to live products in Lemon Squeezy
* Re-sync plans to pull live products
* Warning will disappear automatically
### Support Resources
* [Lemon Squeezy Documentation](https://docs.lemonsqueezy.com)
* [API Reference](https://docs.lemonsqueezy.com/api)
* [Webhook Guide](https://docs.lemonsqueezy.com/help/webhooks)
Lemon Squeezy handles all tax compliance as a Merchant of Record, which means you don't need to worry about VAT, sales tax, or other regional tax requirements.
## Next Steps
Once your Lemon Squeezy integration is complete:
1. **Test the Complete Flow** - Submit a test listing and complete payment
2. **Configure Approval Process** - Set up your content review workflow
3. **Customize Plan Features** - Tailor offerings to your audience
4. **Monitor Performance** - Track conversions and revenue
5. **Optimize Pricing** - Adjust plans based on performance data
Your directory is now ready to accept paid submissions through Lemon Squeezy's robust payment platform!
***
Learn about Stripe payment integration
Set up custom payment solutions
# Stripe Integration for Paid Submissions
Source: https://docs.directify.app/paid-submissions/stripe
Connect your Stripe Account to your directory to start accepting paid submissions and earn money with your directory.
This guide will walk you through integrating Stripe with your directory to accept paid submissions. The setup process has been streamlined - you only need a Stripe Restricted Key, and everything else (webhook creation, product syncing) happens automatically.
**What's New?** The integration process is now fully automated. Simply provide your Stripe Restricted Key, and the system will:
* Create and configure webhooks automatically
* Pull your products and prices automatically
* Handle all the technical setup for you
No more manual webhook configuration or copying multiple keys!
## 1. Enable Paid Submissions
1. Navigate to the **Settings** section of your directory.
2. Go to **Paid Submissions**.
3. Enable **Paid Submissions** and select **Stripe** as the payment provider.
## 2. Create a Stripe Restricted Key
To integrate Stripe securely, you need to create a Restricted Key with specific permissions.
### Quick Setup (Recommended)
Click the button below to create a pre-configured Restricted Key with all required permissions:
**[Create Restricted Key in Stripe →](https://dashboard.stripe.com/apikeys/create?name=Directify%20Paid%20Submissions\&permissions%5B%5D=rak_product_read\&permissions%5B%5D=rak_price_read\&permissions%5B%5D=rak_plan_read\&permissions%5B%5D=rak_checkout_session_write\&permissions%5B%5D=rak_customer_write\&permissions%5B%5D=rak_webhook_write)**
This link will:
* Pre-fill the key name as "Directify Paid Submissions"
* Automatically select all required permissions
* Take you directly to the Stripe key creation page
### Manual Setup (Alternative)
If you prefer to create the key manually:
1. Log in to your **Stripe Dashboard**.
2. Navigate to **Developers** > **API Keys**.
3. Click **Create restricted key**.
4. Name your key (e.g., "Directify Paid Submissions").
5. Configure the following permissions:
**Required Permissions:**
* **Products**: Read
* **Prices**: Read
* **Plans**: Read
* **Checkout Sessions**: Write
* **Customers**: Write
* **Webhooks**: Write
6. Click **Create key** and copy the generated restricted key.
The restricted key will look like `rk_live_...` for production or `rk_test_...` for testing.
## 3. Connect Your Stripe Account
1. In your directory's **Paid Submissions** settings, paste the **Restricted Key** into the designated field.
2. The **Webhook URL** is automatically displayed - you don't need to manually configure it.
3. Click **Verify Credentials and Pull Plans**.
### What Happens Automatically
When you verify your credentials, the system will:
* ✅ Validate your Stripe restricted key
* ✅ Automatically create a webhook endpoint in your Stripe account
* ✅ Configure the webhook with the required events:
* `customer.subscription.created`
* `customer.subscription.updated`
* `customer.subscription.deleted`
* `customer.created`
* `checkout.session.completed`
* ✅ Store the webhook secret securely
* ✅ Pull all active products and prices from your Stripe account
No manual webhook configuration needed! The webhook is created and configured automatically.
## 4. Create Payment Plans in Stripe
Before syncing, make sure you have products set up in Stripe:
1. Navigate to **Products** in your Stripe dashboard.
2. Create products for your submission plans:
* **Subscription Plans**: Monthly, Yearly, etc.
* **One-Time Payment Plans**: Single submission fee
3. Ensure products are marked as **Active**.
4. Add pricing for each product.
You can create multiple price points for the same product (e.g., monthly and yearly pricing).
## 5. Customize Your Plans
After pulling plans from Stripe, you can customize how they appear to users:
1. Review the imported plans in your directory settings.
2. For each plan, you can:
* Edit the **description**
* Customize **button text**
* Add **features** to display
* Mark plans as **bestseller**
* Add **text below button**
* Hide plans you don't want to offer
3. Click **Save** to finalize your configuration.
## 6. User Experience for Paid Submissions
Once configured, users can submit paid listings to your directory:
1. A user submits their content to the directory.
2. They are directed to the **submission dashboard**.
3. They click **Pay and Submit for Review**.
4. Available **plans** (subscription or one-time payments) are displayed.
5. The user selects a plan and completes payment via Stripe's secure checkout.
6. Upon successful payment, their submission is processed for review.
## Test Mode vs Live Mode
If you use a test restricted key (`rk_test_...`), you'll see a **Test Mode** warning in your settings. Make sure to switch to your live restricted key (`rk_live_...`) when you're ready to accept real payments.
## Troubleshooting
### Webhook Issues
If webhooks aren't working:
1. Check that the webhook endpoint was created successfully in your Stripe Dashboard under **Developers** > **Webhooks**.
2. Verify the webhook URL matches the one shown in your directory settings.
3. Ensure all required events are enabled on the webhook endpoint.
### No Plans Showing Up
If plans aren't syncing:
1. Verify your products are marked as **Active** in Stripe.
2. Check that each product has at least one active price.
3. Ensure your restricted key has **Products** and **Prices** read permissions.
4. Click **Verify Credentials and Pull Plans** again to re-sync.
### Permission Errors
If you see permission errors:
1. Verify your restricted key has all required permissions listed in Step 2.
2. Create a new restricted key if needed and update your settings.
## Conclusion
Your directory is now integrated with Stripe using a streamlined setup process! With just a restricted key, you can:
* ✅ Automatically sync products and prices
* ✅ Auto-configure webhooks
* ✅ Accept subscriptions and one-time payments
* ✅ Securely process payments
If you experience any issues, check the Stripe dashboard for logs and debugging information, or refer to the troubleshooting section above.
***
Global tax-compliant payments with automatic VAT handling
Integrate PayPal, RazorPay, or any payment solution
# Connect Analytics to Your Directory
Source: https://docs.directify.app/settings/analytics
Connect Google Analytics, Plausible, PostHog, or any JavaScript-based analytics tool to your Directify directory in seconds — no code required.
Directify supports any analytics platform that uses a JavaScript snippet. Simply paste your tracking code in the analytics field in your directory settings.
## Examples
### Google Analytics 4
```html theme={null}
```
### Plausible
```html theme={null}
```
### PostHog
```html theme={null}
```
### [DataFast](https://datafa.st/)
```html theme={null}
```
You can add multiple analytics scripts - just paste them all in the analytics field.
# Custom URL Routes for Your Directify Directory
Source: https://docs.directify.app/settings/routes
Customize the URL slugs for listings, categories, blog, forms, and custom pages on your Directify directory to match your branding and SEO.
You can customize various routes in your directory to match your branding and preferences. This includes routes for listings, categories, blog posts, custom pages, and forms.
## Listings Routes
Configure how your listing URLs are structured:
* **Listing Route**: Set the prefix for listing pages (default: `listings`)
* Example: If set to `tools`, listings will be at `https://yourdomain.com/tools/{listing-slug}`
* **Show Listings Through Category**: When enabled, listings appear under their category URLs
* Default: `https://yourdomain.com/listings/{listing-slug}`
* With categories: `https://yourdomain.com/{category-slug}/{listing-slug}`
If a listing belongs to multiple categories, it will be accessible through all of them.
This cannot be used together with "Hide Category Slug" option.
You need to choose one.
* **Create Listing Route**: Customize the URL for creating new listings (default: `create`)
* Example: `https://yourdomain.com/listings/create`
This one is used for public submissions route.
## Category Routes
Manage how category pages are accessed:
* **Category Route**: Set the prefix for category pages
* Example: `https://yourdomain.com/categories/{category-slug}`
* **Hide Category Slug**: Remove the category prefix from URLs
* Default: `https://yourdomain.com/categories/{category-slug}`
* Hidden: `https://yourdomain.com/{category-slug}`
This cannot be used together with "Show Listings Through Category" option.
You need to choose one.
## Blog Routes
Configure your blog URL structure:
* **Blog Route**: Set the prefix for blog articles
* Example: `https://yourdomain.com/blog/{article-slug}`
## Custom Pages Routes
Set up URLs for custom pages:
* **Custom Page Route**: Define the prefix for custom pages
* Example: `https://yourdomain.com/pages/{custom-page-slug}`
## Form Routes
Customize form page URLs:
* **Form Route**: Set the prefix for form pages
* Example: `https://yourdomain.com/forms/{form-slug}`