Hello! I'm trying to update the content of a page via api and am running into trouble.
As part of the trouble shooting process, I was just trying to get the page itself to verify the service account api key I created works. Here is my curl command I tested, can anyone verify if this is correct?
curl --request GET \
-H "Authorization: Bearer {api_token}" \
--url "https://api.atlassian.com/ex/confluence/{cloud_id}/wiki/api/v2/pages/{page_id}"
The update curl command I was trying was
curl -X PUT \
"https://api.atlassian.com/ex/confluence/{cloud_id}/wiki/api/v2/pages/{page_id}" \
-H "Authorization: Bearer {service_account_token}" \
-H "Content-Type: application/json" \
-d '{
"id": {page_id},
"status": "current",
"title": {page_title},
"version": {
"number": 2
},
"body": {
"representation": "storage",
"value": "<p>This is a test</p>"
}
}'
One correction to my own answer above, because I sent you the wrong way on the auth. Bearer is fine for a scoped token. The api.atlassian.com gateway accepts both Bearer and basic auth, and Atlassian's own service-account token doc uses Authorization: Bearer <token> in its example, so your original header wasn't the problem and switching to basic won't be what fixes this.
https://support.atlassian.com/user-management/docs/manage-api-tokens-for-service-accounts/
With a scoped token the real culprit is almost always the token's scopes. They're locked in when you create the token and can't be added afterwards, so one minted without read:page:confluence fails the GET, and without write:page:confluence it fails the PUT even after the GET works. Create a fresh token with both scopes selected and try again. Worth checking separately that the service account has edit permission on the space too, since a valid token and permission to edit are two different things.
You nailed it, our confluence admin had given the service account permissions to edit/view the space and documents within, but it wasn't added as a user to the space itself.
Thank you so much!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
There are two things that specifically bite people when it's a service account doing the calls, and they're easy to miss:
Service accounts can only create scoped API tokens, and a scoped token behaves differently from a normal personal API token in two ways.
First, it has to go through the gateway URL - api.atlassian.com/ex/confluence/<cloudId>/... - and not your <site>.atlassian.net domain. You're already doing that, so that part's fine.
Second, and this is the likely culprit: a scoped API token is still an API token, not an OAuth access token, so it authenticates with Basic auth (email + token), not a Bearer header. If you're sending Authorization: Bearer <token>, the gateway tries to read it as an OAuth token, which it isn't, and you get the 401.
So before anything else, drop the Bearer header and sanity-check the token with a plain GET using basic auth:
curl -u "your-service-account-email:your-scoped-token" "https://api.atlassian.com/ex/confluence/<cloudId>/wiki/api/v2/pages/<pageId>"
The email is the service account's address, and the token goes in where the password would. If that returns the page, the token is good and it was just the auth scheme.
Once the GET works, the PUT usually only needs two things to be right:
version.number has to be the page's current version + 1 - grab it from the GET response first, otherwise you'll get a version conflict. Adding a short version.message is good practice too.
body should be { "representation": "storage", "value": "<your storage-format markup>" }, and separately, the service account needs edit permission on that page or space - the token working and the account being allowed to edit are two different checks.
If you still get a 401 even with basic auth, it's worth double-checking the token is actually the scoped one tied to the service account - happy to dig in further if you share the status code and response body (with the token redacted).
Hope that helps!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
thank you so much! thats super helpful!
i tried just the generic get curl you posted and got
{"errors":[{"status":404,"code":"NOT_FOUND","title":"Not Found","detail":null}]}
This didn't return a 401 so the auth permissions must be good, but maybe I'm grabbing the wrong document id?
I'm using the id from the url..
https://{my_company}.atlassian.net/wiki/spaces/{my_space}/pages/1063944234/{doc_title}
is 1063944234 not the correct id?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Good news is the id is right - the number in the page URL (1063944234) is the page id the v2 endpoint wants, so you're reading that off the URL correctly.
The 404 is the misleading part here. Confluence returns a 404 on that endpoint in two very different cases - either the page genuinely doesn't exist under the cloudId you're hitting, or the account isn't allowed to see it. It won't hand back a 403 for a page you lack permission on, so a 404 on its own doesn't confirm the auth is fine.
Two things I'd check. First, confirm the cloudId in the gateway URL belongs to this exact site. If your org has more than one Atlassian site, an id from a different one gives you a clean 404 on a page that really exists somewhere else. You can grab the right one from https://<yoursite>.atlassian.net/_edgeConfig/cloudId. Second, make sure the service account has been given access to the space the page sits in. A token with the right scopes still only sees what the account itself can see, and a fresh service account usually isn't a member of any space yet.
Once the cloudId matches and the account can reach the space, that same GET should return the page. If it's still 404 after that, paste the exact URL you're calling with the cloudId redacted and I'll take another look.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi @dillon_cox
Welcome to the Community! If you're still getting an error, could you share:
Those details will help.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey @dillon_cox ,
It might also be helpfull if you could share what error message you are receiving or what the exact problem is that you are encountering.
At first glance I do want to point out that:
"Authorization: Bearer {api_token}
only tells half the story.
Keep in mind that you don't just send the token but depending on if you are using OAuth or Basic Authentication you might also need to base64 encode the {email:token}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.