Posts API
The Posts API lets your backend manage your company’s posts on the GNet network with authenticated calls. It uses the same validation, plan checks, rate limits, trust scoring, moderation routing, and post storage as the Connect portal. There is no multi-step handshake or impersonation exchange: get a Bearer token, then call the door you need. All five doors are owner-scoped.All five methods run on the Connect application host
(
dashboard.grdd.net), not on core.grdd.net. Use
https://dashboard.grdd.net in production and https://dashboard.grdd.dev in
the development environment. Every method requires a Bearer token issued by
GNet core.Authentication and ownership
To obtain a token, see the Get Token API. Send the token in the standard header on every request:griddid supplied in a create
body must be the caller’s own GNET ID (or the authorized parent account). There
is no partner-side admin override or act-on-behalf-of mode.
Authentication failures are the same for every door:
Create a post
The create door publishes a post to the GNet network on behalf of your own company, with a single authenticated call. It produces the same result as creating the post inside the Connect portal — the same validation, plan check, rate limits, trust scoring and moderation routing, in the same order.Endpoint
POSThttps://dashboard.grdd.net/api/partner/posts
Authentication and headers
griddid in the body
must match the GNET ID your token was issued for (or its parent account);
anything else is rejected with 403 not_entitled. There is no impersonation or
act-on-behalf-of mode.
Request body
Top-level fields
detail fields
Post types
postType must be one of:
Exceeding a cap returns
429 rate_limited with a Retry-After header.
typed fields
Five post types require a detail.typed object. A missing or invalid typed
block fails validation with 422.
What the server overrides
These three output fields are decided by the server — send placeholders where the create schema asks for them and read the real values back from the response:status— always recomputed. Companies flagged as post-trusted publish immediately (published); everyone else is queued for moderator review (pending_review). You cannot self-publish by sending"status": "published".slug— always regenerated from yourtitle, scoped to your GNET ID.authorTrustAtPublish— computed from your profile score, partner count, plan tier and account age.
Visibility
If you request"visibility": "public" but your trust score is below the
public-visibility floor, the post is accepted and downgraded to gnet. When
this happens the response includes "visibilityDowngraded": true.
Images
There is no partner image-upload endpoint. Host your images yourself and pass absolute URLs inimageUrls (maximum 4).
Create request example
Create response
201 Created — published immediately
202 Accepted — queued for review
ok boolean. Never treat a 2xx-shaped body as
success without checking it.
Create errors
Retrying safely
Pass anIdempotency-Key header — any unique string per logical post, such as
a UUID you generate before the first attempt.
- Same key, same body → replays the original response instead of creating a second post.
- Same key, different body →
409 idempotency_conflict. - Keys are scoped to your caller identity and expire after 24 hours.
List your posts
The collection door returns the caller’s own inventory, newest first. It has no status or visibility filter, so active posts indraft, pending_review,
scheduled, or published status can be returned. Retired/archived posts are
excluded because retiring a post removes it from this list’s author index.
Endpoint
GEThttps://dashboard.grdd.net/api/partner/posts?limit=20&cursor=1732000000000
Omit both query parameters for the first page. Use the nextCursor from one
response as the cursor on the next request. A null nextCursor means the
last page.
Authentication and headers
Query parameters
The cursor is an exclusive created-at cursor. The API returns posts in descending
created-at order, and
nextCursor is a number when another page exists.
Request shape
The collection GET has no request body.Request example
Response
posts contains MemberPost records, including their current status. If the
page is the last page, the same response has "nextCursor": null.
Errors
Read one post
Use the item read door to inspect one post you own in any status, includingarchived. This is the status-polling door: after a create returns
pending_review, poll this endpoint to see whether post.detail.status is now
published. After retirement, use it to confirm that the status is
archived; the record remains readable even though it no longer appears in the
collection list.
Endpoint
GEThttps://dashboard.grdd.net/api/partner/posts/{id}
Replace {id} with the id returned by the create or collection response.
Authentication and headers
Request shape
The item GET has no request body. The post ID is supplied in the URL path.Request example
Response
post.detail.status: "archived".
Errors
Revise one post
The revision door applies an allow-listed, strict partial update to one owned post. It does not replace the full post: send only the fields that should change.Endpoint
PATCHhttps://dashboard.grdd.net/api/partner/posts/{id}
Authentication and headers
Request shape
The request must contain adetail object. The revision schema is
.partial().strict().refine(non-empty): every field is optional, at least one
field is required, and unknown keys inside detail return 422 validation_error
instead of being silently dropped.
Allow-listed revision fields
The table below is the complete revision shape — no other field can be set through this door.
These fields are not in the revision shape:
status, slug, postType,
expiresAt, pinnedUntil, isSticky, authorTrustAtPublish, and
moderationNote. Sending any of them as top-level keys inside detail is a
422, not a silent no-op. Ownership always comes from the stored post; a
top-level griddid is rejected with 400 bad_request.
Revision rules
- The post must belong to the bearer caller. Another operator receives
403 not_entitled. - The caller’s Connect plan or free trial must allow posting. Otherwise the
response is
403 plan_required. visibilityis locked. Sending the same stored value parses successfully and leaves visibility unchanged; sending a different value returns403 visibility_locked.- Changing
titlegenerates a new slug. The old slug resolves through a 30-day redirect. A revision that does not change the title leaves the slug untouched. - An archived post is read-only and refuses every revision with
409 post_archived. - Revising a
pending_reviewpost keeps its current status; it does not create a second post or change the moderation state.
Request example
Response
Errors
Retire one post
The retirement door is an idempotent archive operation, not hard deletion. It accepts a post in any status, includingdraft, pending_review,
scheduled, published, or archived. The post record remains available to
the item read door; the retired post is removed from the feed and collection
index.
Endpoint
DELETEhttps://dashboard.grdd.net/api/partner/posts/{id}
Authentication and headers
Request shape
The request has no body. Supply the post ID in the URL path.Request example
Response
200 body and is
safe to retry. The route does not hard-delete post:{id}; the stored record is
retained for its two-year TTL, while its feed and author-list indices are
removed.