LinkedIn Lead Gen Form headline 60 characters: variants in bulk

A LinkedIn Lead Gen Form headline holds 60 characters and the details line 160. Queue copy variants as Sume bulk items and check lengths before you paste.

5 min readSume
All posts

A LinkedIn Lead Gen Form takes a headline of up to 60 characters and a details line of up to 160, according to LinkedIn's Lead Gen Form specifications. To test several angles at once, send one Sume bulk run with one item per angle, bind a small output schema, and reject any result whose lengths exceed those limits before it reaches Campaign Manager.

A bulk request is a server-side queue of ordinary Format runs: 1 to 100 items and a concurrency of 1 to 16. The queue has no webhook, so poll its status_url until status is completed, then read counts.failed, because completed only means every item is terminal.

The limits to enforce

The form's details section carries three text fields. Only the first two are copy you would vary between tests.

Form details limits from LinkedIn's Lead Gen Form specifications (read 2026-10-05)
FieldLimitWhere it shows
HeadlineUp to 60 charactersForm details section
DetailsUp to 160 charactersForm details section
Form imageRecommended 552px by 200pxForm details section

One queue, one item per angle

Replace acme/lead-form-copy with a Format you own. Each item carries its own output_schema and a per-item generation_spend_cap_usd; the script reads each child receipt's output after the queue finishes. A structured-output schema makes the run return those two keys, and your code still counts the characters, because a schema alone does not promise a length.

import os, time, uuid, requests

API = "https://api.sume.com"
H = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
props = {"headline": {"type": "string"}, "details": {"type": "string"}}
schema = {"name": "acme/lead-form-copy/v1", "strict": True, "schema": {
    "type": "object", "additionalProperties": False,
    "required": ["headline", "details"], "properties": props}}
angles = ["save time", "cut cost", "reduce risk"]
items = [{"instruction": f"Lead Gen Form offer headline and details. Angle: {a}.",
          "output_schema": schema, "generation_spend_cap_usd": 2} for a in angles]
r = requests.post(f"{API}/v1/formats/acme/lead-form-copy/bulk-runs",
                  headers={**H, "Idempotency-Key": str(uuid.uuid4())},
                  json={"concurrency": 3, "items": items}, timeout=30)
r.raise_for_status()
q = r.json()["data"]
while q["status"] != "completed":
    time.sleep(10)
    q = requests.get(q["status_url"], headers=H, timeout=30).json()["data"]
for it in q["items"]:
    if it["status"] != "completed":
        print(it["index"], it["error"]); continue
    rec = requests.get(f"{API}/v1/format-runs/{it['run_id']}", headers=H, timeout=30)
    out = rec.json()["data"]["output"]
    print(it["index"], len(out["headline"]) <= 60 and len(out["details"]) <= 160)

Reading the result

A failed or canceled item keeps its index, so you can rerun only that angle. Mint a new Idempotency-Key for each batch: replaying a spent key returns 202 with the old queue, not a new one.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume