# Schedule content

> Publish Ur Next Door content later with scheduled_at: ISO 8601 in UTC, 5 minutes to 180 days ahead, time zone conversion, quotas and what happens next.

Source: https://docs.urnextdoor.com/guides/schedule-content/

Every create endpoint accepts `scheduled_at`. With it, the item is saved now and goes live by itself at that time. This works for posts, questions, polls, MCQs, services, jobs and communities.

## The rules

- **Format:** ISO 8601 with a time zone: either `Z` (UTC) or an offset such as `+05:30`. Examples: `2026-10-20T09:30:00Z`, `2026-10-20T15:00:00+05:30`. A time without a zone is rejected, because it is ambiguous.
- **Stored in UTC.** Whatever offset you send, responses show the time in UTC with `Z`.
- **Window:** at least **5 minutes** and at most **180 days** ahead of now. Outside the window the request answers `422 validation_failed` with an error on `scheduled_at`.
- **Scope:** only `content`, the same as publishing now.
- **Quota:** a scheduled create counts against that type's daily quota on the day you schedule it, not the day it goes live.

## Convert your local time to UTC

UTC has no daylight saving changes. Subtract your offset from your local time:

| You want (local) | Offset | Send |
| --- | --- | --- |
| 20 Oct 2026, 15:00 in India (IST) | +05:30 | `2026-10-20T09:30:00Z` |
| 20 Oct 2026, 09:00 in London (BST) | +01:00 | `2026-10-20T08:00:00Z` |
| 20 Oct 2026, 09:00 in New York (EDT) | -04:00 | `2026-10-20T13:00:00Z` |

Or send the local time with its offset (`2026-10-20T15:00:00+05:30`) and let the API convert it. AI agents should state both the local and the UTC time back to you before scheduling.

## Schedule a post

**cURL**

```bash
curl -X POST "https://urnextdoor.com/api/v1/posts" \
  -H "Authorization: Bearer $UND_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
  "title": "Five easy ways to save water at home",
  "body": "<p>Small habits add up. These five saved our building a lot of water this summer.</p><ul><li>Fix dripping taps the same week.</li><li>Run the washing machine only when it is full.</li></ul>",
  "tags": [
    "water",
    "home"
  ],
  "scheduled_at": "2026-10-20T09:30:00Z"
}'
```

**JavaScript**

```js
const res = await fetch("https://urnextdoor.com/api/v1/posts", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.UND_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    title: "Five easy ways to save water at home",
    body: "<p>Small habits add up. These five saved our building a lot of water this summer.</p><ul><li>Fix dripping taps the same week.</li><li>Run the washing machine only when it is full.</li></ul>",
    tags: ["water", "home"],
    scheduled_at: "2026-10-20T09:30:00Z",
  }),
});
console.log(res.status, await res.json());
```

**Python**

```python
import os
import uuid

import requests

api_key = os.environ["UND_API_KEY"]

response = requests.post(
    "https://urnextdoor.com/api/v1/posts",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "title": "Five easy ways to save water at home",
        "body": "<p>Small habits add up. These five saved our building a lot of water this summer.</p><ul><li>Fix dripping taps the same week.</li><li>Run the washing machine only when it is full.</li></ul>",
        "tags": ["water", "home"],
        "scheduled_at": "2026-10-20T09:30:00Z",
    },
    timeout=30,
)
print(response.status_code, response.json())
```

**PHP**

```php
<?php
$apiKey = getenv('UND_API_KEY');

$payload = [
    'title' => 'Five easy ways to save water at home',
    'body' => '<p>Small habits add up. These five saved our building a lot of water this summer.</p><ul><li>Fix dripping taps the same week.</li><li>Run the washing machine only when it is full.</li></ul>',
    'tags' => ['water', 'home'],
    'scheduled_at' => '2026-10-20T09:30:00Z',
];

$ch = curl_init('https://urnextdoor.com/api/v1/posts');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
        'Idempotency-Key: ' . bin2hex(random_bytes(16)),
    ],
    CURLOPT_POSTFIELDS => json_encode($payload),
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);

echo $status, PHP_EOL, $body, PHP_EOL;
```

Sample response: `201 Created`

```json
{
  "ok": true,
  "id": 41,
  "slug": "five-easy-ways-to-save-water-at-home",
  "url": "/posts/five-easy-ways-to-save-water-at-home",
  "web_url": "https://urnextdoor.com/posts/five-easy-ways-to-save-water-at-home",
  "status": "scheduled",
  "scheduled_at": "2026-10-20T09:30:00Z",
  "item": {
    "id": 41,
    "type": "post",
    "slug": "five-easy-ways-to-save-water-at-home"
  },
  "request_id": "9f8e7d6c5b4a3921"
}
```

The response is the usual `201 Created` plus `"status": "scheduled"` and `scheduled_at`. The `web_url` is where the post will live once it is published.

## Scheduled communities are different

A community does not exist until it is created, so a scheduled community answers `202 Accepted` with a scheduled-creation `id` (use it with the scheduling endpoints). The community is created at the time you chose; if its name was taken in the meantime, the creation fails and you are notified. See [Create a community](https://docs.urnextdoor.com/guides/create-community.md).

## What happens at the scheduled time

The item is published exactly as if you had pressed publish on the website: it appears in feeds, on your profile and in its community, and its tags are applied. In [API analytics](https://docs.urnextdoor.com/analytics.md) it still counts as created through the API, with the key that scheduled it.

Until then, you (and only you) can see it in your scheduled list:

- on the website, at **Scheduled** (`https://urnextdoor.com/scheduled`), and
- through the API, with `GET /api/v1/scheduled`.

## Frequently asked questions

### Can I schedule something more than 180 days ahead?

No. The latest allowed time is 180 days from now. Schedule it later, or keep it in your own system until it is inside the window.

### What if I send a time 2 minutes from now?

The request answers 422 with an error on scheduled_at. The earliest allowed time is 5 minutes ahead. To publish right away, leave scheduled_at out.

### Can I change the time after scheduling?

Yes. Use POST /api/v1/scheduled/{type}/{id}/reschedule with a new scheduled_at, or publish it immediately with POST /api/v1/scheduled/{type}/{id}/publish. See the guide to managing scheduled content.

### Does a cancelled scheduled item give my quota back?

No. The quota was used on the day you scheduled it. Cancelling deletes the item but does not restore that day's count.

## Next steps

- [Manage scheduled content](https://docs.urnextdoor.com/guides/manage-scheduled.md): list, reschedule, publish now, cancel.
- [Prompt recipes](https://docs.urnextdoor.com/ai/prompt-recipes.md) for scheduling a week of posts with an agent.
- [Rate limits and daily quotas](https://docs.urnextdoor.com/limits.md).
