shiply.now
Integrations

Add shiply to your product

Your users publish into their own shiply accounts — their billing, their control. You earn 30% of what they pay, every month, for their first 12 months.

30% recurring · 12 monthsNo shiply account needed to apply
Publish with shiply

The exact button your users see — hosted at shiply.now/button/publish-with-shiply.svg.

Apply to integrateRead the docs
For your coding agent

Paste this into your agent

Self-contained — it asks which page you want the button on and your app's URL, then applies, places the button on that page, wires the callback, and publishes. Your agent needs no other context.

Agent brief — copy, paste into Claude Code, Cursor, Codex, or any agent
You are adding a "Publish with shiply" button to THIS product.
shiply.now is a hosting backend: when someone clicks the button they publish
into their OWN shiply account (their billing, their control), and the owner of
this product earns 30% of what they pay, every month, for their first 12 months.

STEP 0 — Ask me these two questions FIRST, then wait for my answers. Do not
write any code until you have both:
  1. Which page or screen should show the "Publish with shiply" button?
     Give me the file/route AND the public URL it's served at — e.g.
     "the dashboard, app/dashboard/page.tsx, live at https://myapp.com/dashboard".
  2. What is this app's public base URL? You'll add an OAuth callback route to
     it — e.g. https://myapp.com/api/shiply/callback.
If either answer is missing or unclear, ask me — never guess the page or the URL.

STEP 1 — Apply for a client_id.
POST https://shiply.now/api/v1/integrate/apply
Content-Type: application/json
{
  "name": "<this product's name>",
  "slug": "<a-url-slug>",                 // becomes shiply.now/connect/<slug>
  "redirect_uris": ["<the callback URL from step 0>"],
  "logoUrl": "<optional logo URL>",
  "use_case": "<one line: what this product is>"
}
-> 201 { "client_id": "mcpc_...", "slug": "<slug>", "status": "pending" }
-> 409 if the slug is taken — pick another and retry
-> 400 { "error": { "code", "message" } } if a redirect_uri is invalid
An admin approves by hand; the client_id activates on approval (the owner gets
an email). If you already applied, don't re-apply — wait for the approval.

STEP 2 — Put the button on the page I named in step 0.
Add it to that page, linking to the connect URL with a FRESH PKCE pair per
click, with the href built server-side:
https://shiply.now/connect/<slug>?response_type=code&redirect_uri=<callback-url>&code_challenge=<S256-of-code_verifier>&code_challenge_method=S256&state=<random-state>
Use the hosted asset so it matches shiply's brand:
  <a href="<the connect URL above>">
    <img src="https://shiply.now/button/publish-with-shiply.svg" alt="Publish with shiply" height="40" />
  </a>
Generate code_verifier + state per click and store code_verifier server-side
keyed by state (or a short-lived cookie) — you need it back at the callback.

STEP 3 — Build the callback route at the URL from step 0.
Verify state matches what you stored, then:
POST https://shiply.now/api/v1/oauth/token
{
  "grant_type": "authorization_code",
  "code": "<code from the callback>",
  "code_verifier": "<the one you stored for this state>",
  "redirect_uri": "<callback-url>",
  "client_id": "<your client_id>"
}
-> { "access_token", "refresh_token", "scope": "platform:sites" }
Encrypt both tokens at rest, one pair per connected user. Refresh with
grant_type=refresh_token every session (refresh_token lasts 90 days from last use).

STEP 4 — Publish on the user's behalf.
Authorization: Bearer <access_token> on:
POST /api/v1/publish                 — ship a new version
GET  /api/v1/sites/<slug>/files      — pull the current files
GET  /api/v1/sites/<slug>/versions   — list versions
GET  /api/v1/me/entitlements         — the user's plan/limits
Scope rule: this token can only touch sites it created through this button —
never any other site on the user's account. Every shiply error is JSON with a
code, a message, and a docs pointer — follow it, don't guess at the fix.

When you're done, tell me in plain English what you built and which page the
button now lives on, plus this line I can hand my admin: "Users click Publish
with shiply, sign up and pay on shiply.now (not through us), and we get a token
that can only publish the sites they make through us — shiply pays us 30%
monthly for their first year. We never see their password or card."
Embed the button

Copy-paste snippets

Drop the button anywhere in your product's UI. All three point at the same connect URL — pick the format that matches your stack.

HTML
<!-- Build the href server-side: it needs a fresh PKCE
     code_challenge + state per click (see the agent brief, step 2). -->
<a href="https://shiply.now/connect/<your-slug>?response_type=code&redirect_uri=<your-callback-url>&code_challenge=<code_challenge>&code_challenge_method=S256&state=<state>">
  <img
    src="https://shiply.now/button/publish-with-shiply.svg"
    alt="Publish with shiply"
    height="40"
  />
</a>
React / JSX
// connectUrl is built server-side (or in a route handler) with a fresh
// PKCE code_challenge + state per render — see the agent brief, step 2.
<a href={connectUrl}>
  <img
    src="https://shiply.now/button/publish-with-shiply.svg?theme=dark"
    alt="Publish with shiply"
    height={40}
  />
</a>
Markdown
[![Publish with shiply](https://shiply.now/button/publish-with-shiply.svg)](https://shiply.now/connect/<your-slug>?response_type=code&redirect_uri=<your-callback-url>&code_challenge=<code_challenge>&code_challenge_method=S256&state=<state>)

?theme=dark swaps to the dark-mode fill; ?label=integrate swaps the copy to “Integrate with shiply”. Combine both if you like.

How it works

Four steps, on your terms

Apply

POST once to get a client_id and a slug. An admin reviews by hand — you're emailed on approval.

Embed

Drop the button (or call the connect URL directly) anywhere a user would want to publish.

They connect

Your user signs up or signs in on shiply.now, picks a plan, and consents. You never see their password or card.

You publish

Exchange the code for a token scoped to sites it created, then call /api/v1/publish whenever they hit publish in your product.

Full integration docs: /docs/platform-connect · Machine manifest: /.well-known/shiply-integration.json

Apply to integrate

Get your client_id

Tell us about your platform. We review by hand and email you when your client_id goes live.

No account required. We reply by email — approval activates your client_id.