Hello,
I created custom metric and attached to one of the components. Then generated API token on account and tried to push some value there:
$ curl --request POST \ --url https://org.atlassian.net/gateway/api/compass/v1/metrics \ --user "$USER_EMAIL:$USER_API_KEY" \ --header "Accept: application/json" \ --header "Content-Type: application/json" \ --data "{ \"metricSourceId\": \"ari:cloud:compass:!id!:metric-source/!id!\", \"value\": $METRIC_VALUE, \"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\" }"
But getting:
{"timestamp":"2025-02-09T21:28:15.096+00:00","status":403,"error":"Forbidden","path":"/external/v1/metrics"}%
Documentation on API endpoint saying that user does not have permissions to push metrics, but have `Product Admin` permissions.
Maybe something with our plan, we use Free at this moment.
Any ideas what could be wrong and what to check?
Thanks everyone in advance!
https://developer.atlassian.com/cloud/compass/components/push-metric-values-using-a-curl-command/
https://developer.atlassian.com/cloud/compass/rest/v2/api-group-metrics/#api-compass-v1-metrics-post
Hi, @Dmytro Slupytskyi !
You're right that Compass admins have permissions to push metric values to metric sources attached to components, as described in https://support.atlassian.com/compass/docs/how-do-compass-permissions-work/
It is possible to set up more detailed permission policies and restrict who can update metric values in Compass premium, but since you're in the free plan, these configurable restrictions shouldn't apply to your example.
That's making me think there might be some disconnect between the identifiers or credentials used for this case. I'm assuming that you copied from the Compass UI the `curl` command placeholders related to the new metric (in the "copy" icon there) so that you are using your own Compass site domain instead of "org.atlassian.net" in https://org.atlassian.net/gateway/api/compass/v1/metrics also with the prepopulated metric source identifier?
An invalid or expired token could also result in a similar error; you can generate a new token for that specific organization in `/manage-profile/security/api-tokens`
If this doesn't solve your issue and you're comfortable sharing the time of your last attempt and your organization domain, we could try taking a deeper look into the application logs to determine what is happening in this specific case.
Thanks a lot for your response!
Yes, token was generated in https://id.atlassian.com/manage-profile/security/api-tokens and even showing that it was last accessed few minutes ago.
My exact steps with organization domain:
$ export USER_EMAIL="my@email"
$ export USER_API_KEY="generated token"
$ export METRIC_VALUE="1"
# use copy icon for curl request
$ curl --request POST \
--url https://gridesports.atlassian.net/gateway/api/compass/v1/metrics \
--user "$USER_EMAIL:$USER_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "{
\"metricSourceId\": \"ari:cloud:compass:!id!:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/38b24391-a08f-4194-8e10-3fd5f52a4267\",
\"value\": $METRIC_VALUE,
\"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\"
}"{"timestamp":"2025-02-10T17:06:15.563+00:00","status":403,"error":"Forbidden","path":"/external/v1/metrics"}
^ response with exact timestamp
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Dmytro Slupytskyi that helps. Just double checking based on the sample payload that you've sent: have you also replaced `!id!` by the cloudId of your site when providing the metric source Id?
I assume the line that you'd provide for that call would be:
\"metricSourceId\": \"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/38b24391-a08f-4194-8e10-3fd5f52a4267\",
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, was replaced before posting that comment :) This is full command that I use without any masking:
$ curl --request POST \
--url https://gridesports.atlassian.net/gateway/api/compass/v1/metrics \
--user "$USER_EMAIL:$USER_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "{
\"metricSourceId\": \"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/38b24391-a08f-4194-8e10-3fd5f52a4267\",
\"value\": $METRIC_VALUE,
\"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\"
}"{"timestamp":"2025-02-10T19:47:09.614+00:00","status":403,"error":"Forbidden","path":"/external/v1/metrics"}
Sorry for confusion!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Dmytro Slupytskyi okay! Going through the logs, I think your request is getting rejected because of XSRF constraints. I'm not sure about why your specific setup is encountering this when some other sites attempting to do the same aren't seeing this situation, but maybe explicitly adding an origin header that matches the target domain would solve this, as:
$ curl --request POST \
--url https://gridesports.atlassian.net/gateway/api/compass/v1/metrics \
--user "$USER_EMAIL:$USER_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Origin: gridesports.atlassian.net" \
--data "{
\"metricSourceId\": \"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/38b24391-a08f-4194-8e10-3fd5f52a4267\",
\"value\": $METRIC_VALUE,
\"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\"
}"
Please, let me know if that helps!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Enrique Serrano Valle thank you for your response! But still even adding Origin it keep failing :(
We activated trial to see if this makes any difference and also solve few limitations of free plan.
$ curl --request POST \
--url https://gridesports.atlassian.net/gateway/api/compass/v1/metrics \
--user "$USER_EMAIL:$USER_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Origin: gridesports.atlassian.net" \
--data "{
\"metricSourceId\": \"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/38b24391-a08f-4194-8e10-3fd5f52a4267\",
\"value\": $METRIC_VALUE,
\"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\"
}"
{"timestamp":"2025-02-11T13:51:07.292+00:00","status":403,"error":"Forbidden","path":"/external/v1/metrics"}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Enrique Serrano Valle mistery solved. Just asked colleague to test it out and it works. Also, when tried to push via https://www.usebruno.com/ , it also works!
Local setup:
$ cat ~/.curlrc
user-agent = "Mozilla/5.0 (Windows NT 6.1; rv:31.0) Gecko/20100101 Firefox/31.0"
referer = ";auto"
connect-timeout = 10
progress-bar
max-time = 90
#verbose
show-error
remote-time
ipv4$ curl --version
curl 8.12.0 (aarch64-apple-darwin24.2.0) libcurl/8.12.0 OpenSSL/3.4.0 (SecureTransport) zlib/1.2.12 brotli/1.1.0 zstd/1.5.6 AppleIDN libssh2/1.11.1 nghttp2/1.64.0 librtmp/2.3
Release-Date: 2025-02-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz MultiSSL NTLM SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd
Once disabled user-agent and referer, start to work:
$ curl --request POST \
--url https://gridesports.atlassian.net/gateway/api/compass/v1/metrics \
--user "$USER_EMAIL:$USER_API_KEY" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "{
\"metricSourceId\": \"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/f59e21dd-66f7-4ce2-8645-dfac214019f5\",
\"value\": $METRIC_VALUE,
\"timestamp\": \"$(date -u +'%Y-%m-%dT%H:%M:%SZ')\"
}"
{"metricSourceId":"ari:cloud:compass:89c28397-c088-47b0-b168-9bef03da7559:metric-source/4ea518f3-4199-466e-a36b-e657bb1a9d23/f59e21dd-66f7-4ce2-8645-dfac214019f5","value":12.0,"timestamp":"2025-02-11T14:43:18Z"}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Glad to hear that removing the user-agent and the referer headers solved the 403s @Dmytro Slupytskyi ! It was the XSRF protection triggering then.
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.